Moved 1.9 branch to trunk
31
ABOUT-NLS
@ -3,9 +3,8 @@ Notes on the Free Translation Project
|
||||
|
||||
Free software is going international! The Free Translation Project is
|
||||
a way to get maintainers of free software, translators, and users all
|
||||
together, so that free software will gradually become able to speak many
|
||||
languages. A few packages already provide translations for their
|
||||
messages.
|
||||
together, so that will gradually become able to speak many languages.
|
||||
A few packages already provide translations for their messages.
|
||||
|
||||
If you found this `ABOUT-NLS' file inside a distribution, you may
|
||||
assume that the distributed package does use GNU `gettext' internally,
|
||||
@ -16,7 +15,7 @@ this package with messages translated.
|
||||
Installers will find here some useful hints. These notes also
|
||||
explain how users should proceed for getting the programs to use the
|
||||
available translations. They tell how people wanting to contribute and
|
||||
work on translations can contact the appropriate team.
|
||||
work at translations should contact the appropriate team.
|
||||
|
||||
When reporting bugs in the `intl/' directory or bugs which may be
|
||||
related to internationalization, you should tell about the version of
|
||||
@ -56,27 +55,27 @@ internationalization, predating GNU `gettext'.
|
||||
|
||||
By default, this package will be installed to allow translation of
|
||||
messages. It will automatically detect whether the system already
|
||||
provides the GNU `gettext' functions. If not, the included GNU
|
||||
`gettext' library will be used. This library is wholly contained
|
||||
within this package, usually in the `intl/' subdirectory, so prior
|
||||
installation of the GNU `gettext' package is _not_ required.
|
||||
Installers may use special options at configuration time for changing
|
||||
the default behaviour. The commands:
|
||||
provides the GNU `gettext' functions. If not, the GNU `gettext' own
|
||||
library will be used. This library is wholly contained within this
|
||||
package, usually in the `intl/' subdirectory, so prior installation of
|
||||
the GNU `gettext' package is _not_ required. Installers may use
|
||||
special options at configuration time for changing the default
|
||||
behaviour. The commands:
|
||||
|
||||
./configure --with-included-gettext
|
||||
./configure --disable-nls
|
||||
|
||||
will, respectively, bypass any pre-existing `gettext' to use the
|
||||
will respectively bypass any pre-existing `gettext' to use the
|
||||
internationalizing routines provided within this package, or else,
|
||||
_totally_ disable translation of messages.
|
||||
|
||||
When you already have GNU `gettext' installed on your system and run
|
||||
configure without an option for your new package, `configure' will
|
||||
probably detect the previously built and installed `libintl.a' file and
|
||||
will decide to use this. This might not be desirable. You should use
|
||||
the more recent version of the GNU `gettext' library. I.e. if the file
|
||||
`intl/VERSION' shows that the library which comes with this package is
|
||||
more recent, you should use
|
||||
will decide to use this. This might be not what is desirable. You
|
||||
should use the more recent version of the GNU `gettext' library. I.e.
|
||||
if the file `intl/VERSION' shows that the library which comes with this
|
||||
package is more recent, you should use
|
||||
|
||||
./configure --with-included-gettext
|
||||
|
||||
@ -87,7 +86,7 @@ and therefore it will not be used. The reason is that even an
|
||||
emulation of `gettext' on top of `catgets' could not provide all the
|
||||
extensions of the GNU `gettext' library.
|
||||
|
||||
Internationalized packages usually have many `po/LL.po' files, where
|
||||
Internationalized packages have usually many `po/LL.po' files, where
|
||||
LL gives an ISO 639 two-letter code identifying the language. Unless
|
||||
translations have been forbidden at `configure' time by using the
|
||||
`--disable-nls' switch, all available translations are installed
|
||||
|
44
AUTHORS
@ -3,6 +3,8 @@ Maintainer: Werner Koch <wk@gnupg.org>
|
||||
Bug reports: <bug-gnupg@gnu.org>
|
||||
Security related bug reports: <security@gnupg.org>
|
||||
|
||||
Please note that this file is for the 1.9 branch of GnuPG.
|
||||
|
||||
|
||||
Authors
|
||||
=======
|
||||
@ -28,6 +30,9 @@ Edmund GRIMLEY EVANS <edmundo@rano.org> Translations [eo]
|
||||
Florian Weimer <fw@deneb.enyo.de> Assigns past and future changes
|
||||
(changed:g10/parse-packet.c, include/iobuf.h, util/iobuf.c)
|
||||
|
||||
g10 Code GmbH <info@g10code.com> Assigns past and future changes
|
||||
(all work since 2001 as indicated by mail addresses in ChangeLogs)
|
||||
|
||||
Gaël Quéri <gael@lautre.net> Translations [fr]
|
||||
(fixed a lot of typos)
|
||||
|
||||
@ -50,8 +55,6 @@ Laurentiu Buzdugan <lbgnupg@rolix.org> Translations [ro]
|
||||
|
||||
Magda Procha'zkova' <magda@math.muni.cz> Translations [cs]
|
||||
|
||||
Meng Jie <zuxyhere@eastday.com> Translations [zh_CN]
|
||||
|
||||
Michael Roth <mroth@nessie.de> Assigns changes.
|
||||
(wrote cipher/des.c., changes and bug fixes all over the place)
|
||||
|
||||
@ -59,9 +62,15 @@ Michal Majer <mmajer@econ.umb.sk> Translations [sk]
|
||||
|
||||
Marco d'Itri <md@linux.it> Translations [it]
|
||||
|
||||
Marcus Brinkmann <marcus@g10code.de>
|
||||
(gpgconf and fixes all over the place)
|
||||
|
||||
Matthew Skala <mskala@ansuz.sooke.bc.ca> Disclaimer
|
||||
(wrote cipher/twofish.c)
|
||||
|
||||
Moritz Schulte <moritz@g10code.com>
|
||||
(ssh support gpg-agent)
|
||||
|
||||
Niklas Hernaeus <nh@df.lth.se> Disclaimer
|
||||
(weak key patches)
|
||||
|
||||
@ -96,15 +105,13 @@ Rafael Caetano dos Santos <rcaetano@linux.ime.usp.br> Translations [pt_BR]
|
||||
|
||||
Toomas Soome <tsoome@ut.ee> Translations [et]
|
||||
|
||||
Trond Endrestøl <Trond.Endrestol@fagskolen.gjovik.no> Translations [nb]
|
||||
|
||||
Urko Lusa <ulusa@euskalnet.net> Translations [es]
|
||||
Jaime Sua'rez <jjsuarez@iname.com> Translations [es]
|
||||
Urko Lusa <ulusa@euskalnet.net> Translations [es_ES]
|
||||
|
||||
Walter Koch <koch@u32.de> Translations [de]
|
||||
|
||||
Werner Koch <wk@gnupg.org> Assigns GNU Privacy Guard and future changes.
|
||||
(started the whole thing)
|
||||
(started the whole thing, wrote the S/MIME extensions, the
|
||||
smartcard daemon and the gpg-agent)
|
||||
|
||||
Yosiaki IIDA <iida@ring.gr.jp> Translations [ja]
|
||||
|
||||
@ -113,28 +120,15 @@ Yosiaki IIDA <iida@ring.gr.jp> Translations [ja]
|
||||
Other authors
|
||||
=============
|
||||
|
||||
This program uses the zlib compression library written by
|
||||
Jean-loup Gailly and Mark Adler.
|
||||
|
||||
Most of the stuff in mpi has been taken from the GMP library by
|
||||
Torbjorn Granlund <tege@noisy.tmg.se>.
|
||||
|
||||
The Rijndael implementation (cipher/rijndael.c) is based on the
|
||||
public domain reference code provided for the AES selection process.
|
||||
The Rijndael algorithm is due to Joan Daemen and Vincent Rijmen.
|
||||
|
||||
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 common/libestream.[ch] are maintained as a separate project
|
||||
by g10 Code GmbH. These files, as used here, are considered part of
|
||||
GnuPG.
|
||||
|
||||
The RPM specs file scripts/gnupg.spec has been contributed by
|
||||
several people.
|
||||
|
||||
The files below scripts/conf-w32brg/ is a contribution to GnuPG by
|
||||
Brian Gladman and not to be considered a proper part of GnuPG.
|
||||
|
||||
|
||||
Copyright 1998, 1999, 2000, 2001, 2002, 2004 Free Software Foundation, Inc.
|
||||
Copyright 1998, 1999, 2000, 2001, 2002, 2004,
|
||||
2005 Free Software Foundation, Inc.
|
||||
|
||||
This file is free software; as a special exception the author gives
|
||||
unlimited permission to copy and/or distribute it, with or without
|
||||
|
12
BUGS
@ -1,12 +0,0 @@
|
||||
Please see
|
||||
|
||||
http://bugs.gnupg.org/
|
||||
|
||||
for a list of known bugs in GnuPG. We don't distribute this list with
|
||||
the package any longer because a more current one with notes in which
|
||||
version the bug is fixed can be found online.
|
||||
|
||||
For security related bugs, please contact <security@gnupg.org> which
|
||||
directs mails only to the core developers. If you need to encrypt the
|
||||
report you should use the public keys of the maintainer and of 2 or 3
|
||||
other active developers (consult the ChangeLog and AUTHORS).
|
6
COPYING
@ -2,7 +2,7 @@
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
||||
51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
@ -305,7 +305,7 @@ the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
@ -313,7 +313,7 @@ Also add information on how to contact you by electronic and paper mail.
|
||||
If the program is interactive, make it output a short notice like this
|
||||
when it starts in an interactive mode:
|
||||
|
||||
Gnomovision version 69, Copyright (C) year name of author
|
||||
Gnomovision version 69, Copyright (C) year name of author
|
||||
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
52
INSTALL
@ -1,16 +1,13 @@
|
||||
Installation Instructions
|
||||
*************************
|
||||
Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002 Free Software
|
||||
Foundation, Inc.
|
||||
|
||||
Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004 Free
|
||||
Software Foundation, Inc.
|
||||
|
||||
This file is free documentation; the Free Software Foundation gives
|
||||
This file is free documentation; the Free Software Foundation gives
|
||||
unlimited permission to copy, distribute and modify it.
|
||||
|
||||
Basic Installation
|
||||
==================
|
||||
|
||||
These are generic installation instructions.
|
||||
These are generic installation instructions.
|
||||
|
||||
The `configure' shell script attempts to guess correct values for
|
||||
various system-dependent variables used during compilation. It uses
|
||||
@ -70,9 +67,9 @@ The simplest way to compile this package is:
|
||||
Compilers and Options
|
||||
=====================
|
||||
|
||||
Some systems require unusual options for compilation or linking that the
|
||||
`configure' script does not know about. Run `./configure --help' for
|
||||
details on some of the pertinent environment variables.
|
||||
Some systems require unusual options for compilation or linking that
|
||||
the `configure' script does not know about. Run `./configure --help'
|
||||
for details on some of the pertinent environment variables.
|
||||
|
||||
You can give `configure' initial values for configuration parameters
|
||||
by setting variables in the command line or in the environment. Here
|
||||
@ -85,7 +82,7 @@ is an example:
|
||||
Compiling For Multiple Architectures
|
||||
====================================
|
||||
|
||||
You can compile the package for more than one kind of computer at the
|
||||
You can compile the package for more than one kind of computer at the
|
||||
same time, by placing the object files for each architecture in their
|
||||
own directory. To do this, you must use a version of `make' that
|
||||
supports the `VPATH' variable, such as GNU `make'. `cd' to the
|
||||
@ -102,19 +99,19 @@ for another architecture.
|
||||
Installation Names
|
||||
==================
|
||||
|
||||
By default, `make install' will install the package's files in
|
||||
By default, `make install' will install the package's files in
|
||||
`/usr/local/bin', `/usr/local/man', etc. You can specify an
|
||||
installation prefix other than `/usr/local' by giving `configure' the
|
||||
option `--prefix=PREFIX'.
|
||||
option `--prefix=PATH'.
|
||||
|
||||
You can specify separate installation prefixes for
|
||||
architecture-specific files and architecture-independent files. If you
|
||||
give `configure' the option `--exec-prefix=PREFIX', the package will
|
||||
use PREFIX as the prefix for installing programs and libraries.
|
||||
give `configure' the option `--exec-prefix=PATH', the package will use
|
||||
PATH as the prefix for installing programs and libraries.
|
||||
Documentation and other data files will still use the regular prefix.
|
||||
|
||||
In addition, if you use an unusual directory layout you can give
|
||||
options like `--bindir=DIR' to specify different values for particular
|
||||
options like `--bindir=PATH' to specify different values for particular
|
||||
kinds of files. Run `configure --help' for a list of the directories
|
||||
you can set and what kinds of files go in them.
|
||||
|
||||
@ -125,7 +122,7 @@ option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
|
||||
Optional Features
|
||||
=================
|
||||
|
||||
Some packages pay attention to `--enable-FEATURE' options to
|
||||
Some packages pay attention to `--enable-FEATURE' options to
|
||||
`configure', where FEATURE indicates an optional part of the package.
|
||||
They may also pay attention to `--with-PACKAGE' options, where PACKAGE
|
||||
is something like `gnu-as' or `x' (for the X Window System). The
|
||||
@ -140,11 +137,11 @@ you can use the `configure' options `--x-includes=DIR' and
|
||||
Specifying the System Type
|
||||
==========================
|
||||
|
||||
There may be some features `configure' cannot figure out automatically,
|
||||
but needs to determine by the type of machine the package will run on.
|
||||
Usually, assuming the package is built to be run on the _same_
|
||||
architectures, `configure' can figure that out, but if it prints a
|
||||
message saying it cannot guess the machine type, give it the
|
||||
There may be some features `configure' cannot figure out
|
||||
automatically, but needs to determine by the type of machine the package
|
||||
will run on. Usually, assuming the package is built to be run on the
|
||||
_same_ architectures, `configure' can figure that out, but if it prints
|
||||
a message saying it cannot guess the machine type, give it the
|
||||
`--build=TYPE' option. TYPE can either be a short name for the system
|
||||
type, such as `sun4', or a canonical name which has the form:
|
||||
|
||||
@ -170,9 +167,9 @@ eventually be run) with `--host=TYPE'.
|
||||
Sharing Defaults
|
||||
================
|
||||
|
||||
If you want to set default values for `configure' scripts to share, you
|
||||
can create a site shell script called `config.site' that gives default
|
||||
values for variables like `CC', `cache_file', and `prefix'.
|
||||
If you want to set default values for `configure' scripts to share,
|
||||
you can create a site shell script called `config.site' that gives
|
||||
default values for variables like `CC', `cache_file', and `prefix'.
|
||||
`configure' looks for `PREFIX/share/config.site' if it exists, then
|
||||
`PREFIX/etc/config.site' if it exists. Or, you can set the
|
||||
`CONFIG_SITE' environment variable to the location of the site script.
|
||||
@ -181,7 +178,7 @@ A warning: not all `configure' scripts look for a site script.
|
||||
Defining Variables
|
||||
==================
|
||||
|
||||
Variables not defined in a site shell script can be set in the
|
||||
Variables not defined in a site shell script can be set in the
|
||||
environment passed to `configure'. However, some packages may run
|
||||
configure again during the build, and the customized values of these
|
||||
variables may be lost. In order to avoid this problem, you should set
|
||||
@ -195,7 +192,8 @@ overridden in the site shell script).
|
||||
`configure' Invocation
|
||||
======================
|
||||
|
||||
`configure' recognizes the following options to control how it operates.
|
||||
`configure' recognizes the following options to control how it
|
||||
operates.
|
||||
|
||||
`--help'
|
||||
`-h'
|
||||
|
75
Makefile.am
@ -1,7 +1,8 @@
|
||||
# Copyright (C) 1998,1999,2000,2001,2003 Free Software Foundation, Inc.
|
||||
#
|
||||
# Makefile.am - main makefile for NewPG/GnuPG
|
||||
# Copyright (C) 2001, 2004 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is part of GnuPG.
|
||||
#
|
||||
#
|
||||
# GnuPG is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
@ -14,40 +15,68 @@
|
||||
#
|
||||
# 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
|
||||
# USA.
|
||||
|
||||
## Process this file with automake to produce Makefile.in
|
||||
|
||||
ACLOCAL_AMFLAGS = -I m4
|
||||
DISTCHECK_CONFIGURE_FLAGS = --enable-selinux-support
|
||||
AUTOMAKE_OPTIONS = dist-bzip2 filename-length-max=99
|
||||
ACLOCAL_AMFLAGS = -I m4 -I gl/m4
|
||||
AUTOMAKE_OPTIONS = dist-bzip2
|
||||
|
||||
if CROSS_COMPILING
|
||||
checks =
|
||||
else
|
||||
checks = checks
|
||||
endif
|
||||
|
||||
SUBDIRS = m4 intl zlib util mpi cipher tools g10 keyserver po doc ${checks}
|
||||
EXTRA_DIST = scripts/config.rpath PROJECTS BUGS config.h.in autogen.sh
|
||||
EXTRA_DIST = scripts/config.rpath autogen.sh README.CVS
|
||||
DISTCLEANFILES = g10defs.h
|
||||
|
||||
# Add all the files listed in "distfiles" files to the distribution,
|
||||
# apply version numbers to some files and create a VERSION file which
|
||||
# we need for the Prereq: patch file trick.
|
||||
if BUILD_GPGSM
|
||||
kbx = kbx
|
||||
else
|
||||
kbx =
|
||||
endif
|
||||
|
||||
|
||||
if BUILD_GPG
|
||||
gpg = g10
|
||||
# fixme: Noy yet ready for a build
|
||||
keyserver =
|
||||
else
|
||||
gpg =
|
||||
keyserver =
|
||||
endif
|
||||
if BUILD_GPGSM
|
||||
sm = sm
|
||||
else
|
||||
sm =
|
||||
endif
|
||||
if BUILD_AGENT
|
||||
agent = agent
|
||||
else
|
||||
agent =
|
||||
endif
|
||||
if BUILD_SCDAEMON
|
||||
scd = scd
|
||||
else
|
||||
scd =
|
||||
endif
|
||||
|
||||
if HAVE_W32_SYSTEM
|
||||
tests =
|
||||
else
|
||||
tests = tests
|
||||
endif
|
||||
|
||||
SUBDIRS = m4 intl gl jnlib common ${kbx} \
|
||||
${gpg} ${keyserver} ${sm} ${agent} ${scd} tools po doc ${tests}
|
||||
|
||||
dist-hook:
|
||||
@set -e; \
|
||||
for file in `cd $(top_srcdir); \
|
||||
find scripts mpi include -type f -name distfiles`; do \
|
||||
find scripts include -type f -name distfiles`; do \
|
||||
dir=`dirname $$file` ; $(mkinstalldirs) $(distdir)/$$dir ; \
|
||||
for i in distfiles `cat $(top_srcdir)/$$file` ; do \
|
||||
ln $(top_srcdir)/$$dir/$$i $(distdir)/$$dir/$$i 2> /dev/null \
|
||||
|| cp -p $(top_srcdir)/$$dir/$$i $(distdir)/$$dir/$$i; \
|
||||
done ; \
|
||||
done
|
||||
@set -e; \
|
||||
sed -e 's/@pkg_version@/$(VERSION)/g' \
|
||||
$(top_srcdir)/scripts/gnupg.spec.in \
|
||||
> $(distdir)/gnupg.spec
|
||||
echo "$(VERSION)" > $(distdir)/VERSION
|
||||
|
||||
|
||||
|
||||
|
46
NOTES
@ -1,46 +0,0 @@
|
||||
Checking ElGamal signatures is really slow and the reason for the long
|
||||
running time on parts o my keyring. Because somekeys are also checked at startup, this is even worser. I should invalidate my self signature with algo 16 or 20.
|
||||
|
||||
|
||||
SCO UnixWare/7.1.0 reported by Allan Clark <allanc@sco.com> for 0.9.8
|
||||
|
||||
|
||||
Some other reported cpu-vendor-os strings:
|
||||
|
||||
hppa1.1-hp-hpux10.20
|
||||
mips-sgi-irix6.2
|
||||
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
|
||||
|
||||
|
||||
|
||||
|
||||
tried to compile GnuPG on AIX 4.3 on a power CPU based machine. It
|
||||
doesn't work out of the box but i found a way to do so:
|
||||
|
||||
PowerPC based machines:
|
||||
CFLAGS="-g -O2 -mcpu=powerpc" ./configure --disable-asm --disable-dynload
|
||||
+--enable-static-rnd=egd
|
||||
|
||||
Power1 and Power2 machines:
|
||||
CFLAGS="-g -O2 -mcpu=power" ./configure --disable-asm --disable-dynload
|
||||
+--enable-static-rnd=egd
|
||||
|
||||
|
102
OBUGS
@ -1,102 +0,0 @@
|
||||
List of fixed bugs
|
||||
--------------------
|
||||
|
||||
(format: severity: [ *] to [***], no, first reported, by, version)
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
[ *] #1
|
||||
pgp263in works fine even with a source file with CR,LF but GnuPG
|
||||
and pgp263in has problems if the clearsign has been created by
|
||||
pgp263ia. The reason for this problem is that pgp2 sometimes
|
||||
converts CR,LF to CR,CR,LF and to fix for this it hashes both
|
||||
versions. I was able to reproduce such a problem, that PGP263in
|
||||
was not able to verify it's own signature.
|
||||
FIX: 1999-05-19 (Most cases are now handled)
|
||||
|
||||
[***] #2 1999-02-21
|
||||
Problem while importing or deleting public keys in 0.9.3 - 0.9.2
|
||||
worked fine. Error message:
|
||||
gpg:[stdin]: key A6A59DB9: secret key not found: public key not found
|
||||
FIX: 1999-02-22 wk
|
||||
|
||||
[ *] #5
|
||||
/home/jam/.gnupg/pubring.gpg: can't open gdbm file: Can't be writer
|
||||
keyblock resource `/home/jam/.gnupg/pubring.gpg': file open error
|
||||
OOPS in close enum_keyblocks - ignored
|
||||
[gdbm is experimental and will be replaced by the new keybox code]
|
||||
FIX: 1999-07-22 (Fixed the second error, there will be no fix for
|
||||
the first one, because GDBM is to be replaced)
|
||||
|
||||
[ *] #7 1999-02-22 <dwpalmer@dwpalm.jf.intel.com> 0.9.3
|
||||
Conventional encryption incompatibility:
|
||||
$ gpg -c --cipher-algo cast5 --compress-algo 1 --no-comment secrets.txt
|
||||
Creates a file that gpg can decrypt, but PGP 5.5 has problems with it.
|
||||
PGP decrypts 6416k out of 6424k, then complains with "PGP Warning",
|
||||
"The keyring contains a bad (corrupted) PGP packet". The resulting
|
||||
file is missing information from the front.
|
||||
FIX: 1999-02-26 temporary fix in encrypt_simple()
|
||||
|
||||
|
||||
[ *] #8 1999-02-25 <kazu@iijlab.net> 0.9.3
|
||||
%gpg --encrypt -r kazu@iijlab.net --batch foo
|
||||
gpg: Warning: using insecure memory!
|
||||
gpg: 11C23F61: no info to calculate a trust probability
|
||||
This creates a symmetrically encrypted message WITHOUT a session key
|
||||
encrypted with public cryptographic(i.e. foo.gpg). This is probably
|
||||
FIX: 199-02-26 wk
|
||||
|
||||
[ **] #9 1999-02-25
|
||||
Misalignment in md5.c#md5_write.
|
||||
FIX: 1999-02-26 wk
|
||||
|
||||
[ **] #10 1999-03-01
|
||||
Armor detection code is broken. Direct import of keyrings is not possible.
|
||||
FIX: 1999-03-02 wk
|
||||
|
||||
[***] #11 1999-02-25
|
||||
"cipher algo 10 not found".
|
||||
FIX: 1999-02-25 wk
|
||||
|
||||
[ **] #12 1999-03-10
|
||||
gpg --list-secret-keys --with-colon SEGVs
|
||||
FIX: 1999-03-10
|
||||
|
||||
[ *] #13 1999-04-05
|
||||
Trying to generate very large keys fails with a BUG in read_pool()
|
||||
FIX: 1999-04-06
|
||||
|
||||
|
||||
[ *] #14 1999-04-05 <anonymous>
|
||||
If you use --s2k-cipher-algo twofish, the the program crashes with
|
||||
a BUG at line 226 of passphrase.c.
|
||||
FIX: 1999-04-06
|
||||
|
||||
|
||||
[ **] #15 1999-04-05
|
||||
Hash calculation for subkey bindings is not according to rfc2440 if
|
||||
a 4 byte length header is used for the subkey.
|
||||
FIX: 1999-04-06
|
||||
|
||||
[***] #16 1999-03-23 <jafo@tummy.com>
|
||||
Verifying detached signatures with an empty file yields a rc of 0.
|
||||
FIX: 1999-05-06
|
||||
|
||||
[ **] #17 1999-05-18 <Bodo_Moeller@public.uni-hamburg.de> 0.9.6
|
||||
Import does not detect identical user IDs.
|
||||
FIX: 1999-05-22
|
||||
|
||||
[ **] #19 1999-06-11
|
||||
"trustdb transaction too large" with about 500 signatures on a key
|
||||
FAEBD5FC.
|
||||
FIX: 1999-07-12 (less memory requirement and increased the limit)
|
||||
|
||||
[ **] #20 1999-06-16 <jashley@yorktown.designlab.ukans.edu> 0.9.7
|
||||
Using "addkey" in the edit menu with more than 1 subkey leads to
|
||||
"out of secure memory" in some cases.
|
||||
FIX: 1999-06-17 (Twofish uses too much memory and the memory
|
||||
becomes fragmented - workaround is using CAST5 to protect passphrases)
|
||||
|
||||
[ *] #21 1999-06-17
|
||||
Ctrl-D does not work correct for messages entered at the tty.
|
||||
FIX: 1999-06-18 (Better EOF detection on terminals)
|
||||
|
46
PROJECTS
@ -1,46 +0,0 @@
|
||||
|
||||
* Change the internal representation of keyid into a struct which
|
||||
can also hold the localid and extend the localid to hold information
|
||||
of the subkey number because two subkeys may have the same keyid.
|
||||
|
||||
* Add a way to override the current cipher/md implementations
|
||||
by others (using extensions)
|
||||
|
||||
* Not GnuPG related: What about option completion in bash?
|
||||
Can "--dump-options" be used for this or should we place the
|
||||
options in an ELF note section?
|
||||
|
||||
* Split key support (n-out-of-m). Use our own protocol or figure out
|
||||
how PGP does it.
|
||||
|
||||
* add an option to re-create a public key from a secret key; we
|
||||
can do this in trustdb.c:verify_own_keys. (special tool?)
|
||||
Hmmm, we better drop the duplication of the public part and just keep
|
||||
the secrets in the "secring" - this has the additional that we can
|
||||
put those secrets on a hardware token.
|
||||
|
||||
* write a tool to extract selected keys from a file.
|
||||
|
||||
* Change the buffering to a mbuf like scheme? See Michael's proposal.
|
||||
|
||||
* Keep a list of duplicate, faked or unwanted keyids.
|
||||
|
||||
* The current code has knowledge about the structure of a keyblock.
|
||||
We should add an abstraction layer so that adding support for
|
||||
different certificate structures will become easier.
|
||||
|
||||
* "Michael T. Babcock" <mbabcock@fibrespeed.net> suggested to write
|
||||
an event log so that other software can display a key history or
|
||||
alike with GnuPG results. This should be connected to the keyrings.
|
||||
|
||||
|
||||
|
||||
Copyright 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
|
||||
|
||||
This file is free software; as a special exception the author gives
|
||||
unlimited permission to copy and/or distribute it, with or without
|
||||
modifications, as long as this notice is preserved.
|
||||
|
||||
This file is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
|
||||
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
@ -1,4 +1,4 @@
|
||||
If you are building from Subversion, run the script
|
||||
If you are building from CVS, run the script
|
||||
|
||||
./autogen.sh
|
||||
|
||||
@ -40,11 +40,11 @@ knowledge about the actual tools used by autgen.sh.
|
||||
|
||||
Please don't use autopoint, libtoolize or autoreconf unless you are
|
||||
the current maintainer and want to update the standard configuration
|
||||
files. All those files should be in the repository and only updated
|
||||
manually if the maintainer decides that newer versions are required.
|
||||
The maintainer should also make sure that the required version of
|
||||
automake et al. are properly indicated at the top of configure.ac and
|
||||
take care to copy the files and not merely use symlinks.
|
||||
files. All those files should be in the CVS and only updated manually
|
||||
if the maintainer decides that newer versions are required. The
|
||||
maintainer should also make sure that the required version of automake
|
||||
et al. are properly indicated at the top of configure.ac and take care
|
||||
to copy the files and not merely use symlinks.
|
||||
|
||||
|
||||
|
265
THANKS
@ -1,258 +1,9 @@
|
||||
GnuPG was originally written by Werner Koch. Other people contributed
|
||||
by reporting problems, suggesting various improvements or submitting
|
||||
actual code. Here is a list of those people. Help us keep it complete
|
||||
and free of errors.
|
||||
|
||||
Adam Mitchell adam@cafe21.org
|
||||
Albert Chin china@thewrittenword.com
|
||||
Alec Habig habig@budoe2.bu.edu
|
||||
Allan Clark allanc@sco.com
|
||||
Anand Kumria wildfire@progsoc.uts.edu.au
|
||||
Andreas Haumer andreas@xss.co.at
|
||||
Anthony Carrico acarrico@memebeam.org
|
||||
Anthony Mulcahy anthony@kcn.ne.jp
|
||||
Ariel T Glenn ariel@columbia.edu
|
||||
Bob Mathews bobmathews@mindspring.com
|
||||
Bodo Moeller Bodo_Moeller@public.uni-hamburg.de
|
||||
Brendan O'Dea bod@debian.org
|
||||
Brenno de Winter brenno@dewinter.com
|
||||
Brian M. Carlson karlsson@hal-pc.org
|
||||
Brian Moore bem@cmc.net
|
||||
Brian Warner warner@lothar.com
|
||||
Bryan Fullerton bryanf@samurai.com
|
||||
Bryce Nichols bryce@bnichols.org
|
||||
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
|
||||
Chris Adams cmadams@hiwaay.net
|
||||
Christian Biere christianbiere@gmx.de
|
||||
Christian Kurz shorty@debian.org
|
||||
Christian von Roques roques@pond.sub.org
|
||||
Christopher Oliver oliver@fritz.traverse.net
|
||||
Christian Recktenwald chris@citecs.de
|
||||
Daiki Ueno ueno@unixuser.org
|
||||
Dan Winship danw@helixcode.com
|
||||
Daniel Eisenbud eisenbud@cs.swarthmore.edu
|
||||
Daniel Koening dan@chaosdorf.de
|
||||
Daniel Resare daniel@resare.com
|
||||
Dany Nativel dany@natzo.com
|
||||
Dave Dykstra dwd@bell-labs.com
|
||||
David C Niemi niemi@tuxers.net
|
||||
David Champion dgc@uchicago.edu
|
||||
David D. Scribner dscribner@bigfoot.com
|
||||
David Ellement ellement@sdd.hp.com
|
||||
David Hallinan hallinan@rtd.com
|
||||
David Hollenberg dhollen@ISI.EDU
|
||||
David Mathog MATHOG@seqaxp.bio.caltech.edu
|
||||
David R. Bergstein dbergstein@home.com
|
||||
David Shaw dshaw@jabberwocky.com
|
||||
Detlef Lannert lannert@lannert.rz.uni-duesseldorf.de
|
||||
Dimitri dmitri@advantrix.com
|
||||
Dirk Lattermann dlatt@t-online.de
|
||||
Dirk Meyer dirk.meyer@dinoex.sub.org
|
||||
Disastry Disastry@saiknes.lv
|
||||
Douglas Calvert dfc@anize.org
|
||||
Ed Boraas ecxjo@esperanto.org
|
||||
Edmund GRIMLEY EVANS edmundo@rano.org
|
||||
Edwin Woudt edwin@woudt.nl
|
||||
Enzo Michelangeli em@MailAndNews.com
|
||||
Ernst Molitor ernst.molitor@uni-bonn.de
|
||||
Evgeny Legerov
|
||||
Fabio Coatti cova@ferrara.linux.it
|
||||
Felix von Leitner leitner@amdiv.de
|
||||
fish stiqz fish@analog.org
|
||||
Florian Weimer Florian.Weimer@rus.uni-stuttgart.de
|
||||
Francesco Potorti pot@gnu.org
|
||||
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
|
||||
Gabriel Rosenkoetter gr@eclipsed.net
|
||||
Gaël Quéri gael@lautre.net
|
||||
Gene Carter gcarter@lanier.com
|
||||
Geoff Keating geoffk@ozemail.com.au
|
||||
Georg Schwarz georg.schwarz@iname.com
|
||||
Giampaolo Tomassoni g.tomassoni@libero.it
|
||||
Gilbert Fernandes gilbert_fernandes@hotmail.com
|
||||
Greg Louis glouis@dynamicro.on.ca
|
||||
Greg Troxel gdt@ir.bbn.com
|
||||
Gregory Steuck steuck@iname.com
|
||||
Harald Denker harry@hal.westfalen.de
|
||||
Holger Baust Holger.Baust@freenet-ag.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
|
||||
Ingo Klöcker kloecker@kde.org
|
||||
Ivo Timmermans itimmermans@bigfoot.com
|
||||
Jan Krueger max@physics.otago.ac.nz
|
||||
Jan Niehusmann jan@gondor.com
|
||||
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
|
||||
Jeffery Von Ronne jronne@ics.uci.edu
|
||||
Jens Bachem bachem@rrz.uni-koeln.de
|
||||
Jeroen C. van Gelderen jeroen@vangelderen.org
|
||||
J Horacio MG homega@ciberia.es
|
||||
J. Michael Ashley jashley@acm.org
|
||||
Jim Bauer jfbauer@home.com
|
||||
Jim Small cavenewt@my-deja.com
|
||||
Joachim Backes backes@rhrk.uni-kl.de
|
||||
Joe Rhett jrhett@isite.net
|
||||
Joerg Honegger Joerg.Honegger@hp.com
|
||||
John A. Martin jam@jamux.com
|
||||
John Clizbe JPClizbe@comcast.net
|
||||
John R. Shannon john@johnrshannon.com
|
||||
Johnny Teveßen j.tevessen@gmx.de
|
||||
Jörg Schilling schilling@fokus.gmd.de
|
||||
Jos Backus Jos.Backus@nl.origin-it.com
|
||||
Joseph Walton joe@kafsemo.org
|
||||
Juan F. Codagnone juam@arnet.com.ar
|
||||
Jun Kuriyama kuriyama@sky.rim.or.jp
|
||||
Kahil D. Jallad kdj4@cs.columbia.edu
|
||||
Karl Fogel kfogel@guanabana.onshore.com
|
||||
Karsten Thygesen karthy@kom.auc.dk
|
||||
Katsuhiro Kondou kondou@nec.co.jp
|
||||
Kazu Yamamoto kazu@iijlab.net
|
||||
Kazuyoshi Kakihara
|
||||
Keith Clayton keith@claytons.org
|
||||
Kevin Ryde user42@zip.com.au
|
||||
Klaus Singvogel ks@caldera.de
|
||||
Kurt Garloff garloff@suse.de
|
||||
Lars Kellogg-Stedman lars@bu.edu
|
||||
L. Sassaman rabbi@quickie.net
|
||||
M Taylor mctaylor@privacy.nb.ca
|
||||
Marcel Waldvogel mwa@arl.wustl.edu
|
||||
Marco d'Itri md@linux.it
|
||||
Marco Parrone marc0@autistici.org
|
||||
Marcus Brinkmann Marcus.Brinkmann@ruhr-uni-bochum.de
|
||||
Mark Adler madler@alumni.caltech.edu
|
||||
Mark Elbrecht snowball3@bigfoot.com
|
||||
Mark Pettit pettit@yahoo-inc.com
|
||||
Markus Friedl Markus.Friedl@informatik.uni-erlangen.de
|
||||
Martin Kahlert martin.kahlert@provi.de
|
||||
Martin Hamilton
|
||||
Martin Schulte schulte@thp.uni-koeln.de
|
||||
Matt Kraai kraai@alumni.carnegiemellon.edu
|
||||
Matthew Skala mskala@ansuz.sooke.bc.ca
|
||||
Matthew Wilcox matthew@wil.cx
|
||||
Matthias Urlichs smurf@noris.de
|
||||
Max Valianskiy maxcom@maxcom.ml.org
|
||||
Michael Engels michael.engels@uni-duesseldorf.de
|
||||
Michael Fischer v. Mollard mfvm@gmx.de
|
||||
Michael Roth mroth@nessie.de
|
||||
Michael Sobolev mss@despair.transas.com
|
||||
Michael Tokarev mjt@tls.msk.ru
|
||||
Nicolas Graner Nicolas.Graner@cri.u-psud.fr
|
||||
Mike Dowling ML.Dowling at tu-bs.de
|
||||
Mike McEwan mike@lotusland.demon.co.uk
|
||||
Neal H Walfield neal@cs.uml.edu
|
||||
Nelson H. F. Beebe beebe@math.utah.edu
|
||||
NIIBE Yutaka gniibe@chroot.org
|
||||
Niklas Hernaeus
|
||||
Nimrod Zimerman zimerman@forfree.at
|
||||
Norihiko Murase skeleten@shillest.net
|
||||
N J Doye nic@niss.ac.uk
|
||||
Oliver Haakert haakert@hsp.de
|
||||
Oskari Jääskeläinen f33003a@cc.hut.fi
|
||||
Pascal Scheffers Pascal@scheffers.net
|
||||
Paul D. Smith psmith@baynetworks.com
|
||||
Per Cederqvist ceder@lysator.liu.se
|
||||
Phil Blundell pb@debian.org
|
||||
Philippe Laliberte arsphl@oeil.qc.ca
|
||||
Peter Fales psfales@lucent.com
|
||||
Peter Gutmann pgut001@cs.auckland.ac.nz
|
||||
Peter Marschall Peter.Marschall@gedos.de
|
||||
Peter Valchev pvalchev@openbsd.org
|
||||
Phong Nguyen Phong.Nguyen@ens.fr
|
||||
Piotr Krukowiecki piotr@pingu.ii.uj.edu.pl
|
||||
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
|
||||
Richard Patterson vectro@yahoo.com
|
||||
Robert Joop rj@rainbow.in-berlin.de
|
||||
Roddy Strachan roddy@satlink.com.au
|
||||
Roger Sondermann r.so@bigfoot.com
|
||||
Roland Rosenfeld roland@spinnaker.rhein.de
|
||||
Roman Pavlik rp@tns.cz
|
||||
Ross Golder rossigee@bigfoot.com
|
||||
Russell Coker russell@coker.com.au
|
||||
Ryan Malayter rmalayter@bai.org
|
||||
Sam Roberts sam@cogent.ca
|
||||
Sami Tolvanen sami@tolvanen.com
|
||||
Sascha Kiefer sk@intertivity.com
|
||||
Scott Worley sworley@chkno.net
|
||||
Sean MacLennan seanm@netwinder.org
|
||||
Sebastian Klemke packet@convergence.de
|
||||
Serge Munhoven munhoven@mema.ucl.ac.be
|
||||
SL Baur steve@xemacs.org
|
||||
Stefan Bellon sbellon@sbellon.de
|
||||
Dr.Stefan.Dalibor Dr.Stefan.Dalibor@bfa.de
|
||||
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
|
||||
Steven Murdoch sjmurdoch@bigfoot.com
|
||||
Susanne Schultz schultz@hsp.de
|
||||
Tavis Ormandy taviso@gentoo.org
|
||||
Ted Cabeen secabeen@pobox.com
|
||||
Thiago Jung Bauermann jungmann@cwb.matrix.com.br
|
||||
Thijmen Klok thijmen@xs4all.nl
|
||||
Thomas Roessler roessler@guug.de
|
||||
Tim Mooney mooney@dogbert.cc.ndsu.nodak.edu
|
||||
Timo Schulz twoaday@freakmail.de
|
||||
Tobias Winkler tobias.winkler@s1998.tu-chemnitz.de
|
||||
Todd Vierling tv@pobox.com
|
||||
TOGAWA Satoshi Satoshi.Togawa@jp.yokogawa.com
|
||||
Tom Spindler dogcow@home.merit.edu
|
||||
Tom Zerucha tzeruch@ceddec.com
|
||||
Tomas Fasth tomas.fasth@twinspot.net
|
||||
Tommi Komulainen Tommi.Komulainen@iki.fi
|
||||
Thomas Klausner wiz@danbala.ifoer.tuwien.ac.at
|
||||
Tomasz Kozlowski tomek@rentec.com
|
||||
Thomas Mikkelsen tbm@image.dk
|
||||
Ulf Möller 3umoelle@informatik.uni-hamburg.de
|
||||
Urko Lusa ulusa@euskalnet.net
|
||||
Vincent P. Broman broman@spawar.navy.mil
|
||||
Volker Quetschke quetschke@scytek.de
|
||||
W Lewis wiml@hhhh.org
|
||||
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
|
||||
Winona Brown win@huh.org
|
||||
Yosiaki IIDA iida@ring.gr.jp
|
||||
Yoshihiro Kajiki kajiki@ylug.org
|
||||
nbecker@hns.com
|
||||
|
||||
Thanks to the German Unix User Group for sponsoring this project,
|
||||
Martin Hamilton for hosting the first mailing list and OpenIT for
|
||||
cheap hosting conditions.
|
||||
|
||||
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.
|
||||
|
||||
Copyright 1998, 1999, 2000, 2001, 2002, 2003,
|
||||
2004 Free Software Foundation, Inc.
|
||||
|
||||
This file is free software; as a special exception the author gives
|
||||
unlimited permission to copy and/or distribute it, with or without
|
||||
modifications, as long as this notice is preserved.
|
||||
|
||||
This file is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
|
||||
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
Alexander Belopolsky belopolsky at mac.com
|
||||
Andrew J. Schorr aschorr at telemetry-investments.com
|
||||
Carl Meijer carlm at prism.co.za
|
||||
Charly Avital shavital at mac.com
|
||||
Kazu Yamamoto kazu at iij.ad.jp
|
||||
Michael Nottebrock michaelnottebrock at gmx.net
|
||||
Ray Link rlink at pitt.edu
|
||||
Richard Lefebvre rick at cerca.umontreal.ca
|
||||
|
275
THOUGHTS
@ -1,275 +0,0 @@
|
||||
How often have we to do a key lookup by mailaddress?.
|
||||
can this be accomplished by an external program?
|
||||
|
||||
|
||||
|
||||
What about using S-Exp to describe the interface to the ciphers instead
|
||||
of simply iterating over them. This way we can easy register a name which
|
||||
can be used as the "hintstr" for --load-extension.
|
||||
|
||||
EGD
|
||||
====
|
||||
Oh, and on embedding egd into the gpg package: I think if you just unpack it
|
||||
into, say, util/egd/* then you can put something like this into configure.in:
|
||||
|
||||
AC_CHECK_PROG(perl_present, perl, true, false)
|
||||
if $perl_present; then
|
||||
AC_PATH_PROG(PERL, perl)
|
||||
(cd util/egd; $PERL Makefile.PL FULLPERL=$PERL INSTALLBIN=$sbindir)
|
||||
fi
|
||||
AM_CONDITIONAL(WITH_EGD, $perl_present)
|
||||
|
||||
and add util/egd to the top-level Makefile directory list inside a WITH_EGD
|
||||
conditional.
|
||||
|
||||
* What shall we do if we have a valid subkey revocation certificate
|
||||
but no subkey binding? Is this a valid but revoked key?
|
||||
|
||||
* use a mmaped file for secure memory if mlock does not work and
|
||||
make sure that this file is always wiped out. Is this really
|
||||
more secure than swapping out to the swap disk? I don't
|
||||
believe so because if an attacker has access to the physical
|
||||
box (and he needs this to look at the swap area) he can also
|
||||
leave a Trojan horse which is far more easier than to analyze
|
||||
memory dumps. Question: Is it possible that a Unix pages
|
||||
an old (left over by some other process) swap page in for
|
||||
another process - this should be considered a serious design
|
||||
flow/bug.
|
||||
|
||||
Date: Mon, 4 Jan 1999 19:34:29 -0800 (PST)
|
||||
From: Matthew Skala <mskala@ansuz.sooke.bc.ca>
|
||||
|
||||
- Signing with an expired key doesn't work by default, does work with a
|
||||
special option.
|
||||
- Verifying a signature that appears to have been made by an expired key
|
||||
after its expiry date but is otherwise good reports the signature as BAD,
|
||||
preferably with a message indicating that it's a key-expiry problem rather
|
||||
than a cryptographically bad signature.
|
||||
- Verifying a signature from a key that is now expired, where the
|
||||
signature was made before the expiry date, reports the signature as
|
||||
GOOD, possibly with a warning that the key has since expired.
|
||||
- Encrypting to an expired key doesn't work by default, does work with a
|
||||
special option.
|
||||
- Decrypting always works, if you have the appropriate secret key and
|
||||
passphrase.
|
||||
|
||||
|
||||
|
||||
==============================
|
||||
[ "-->" indicates a comment by me (wk) ]
|
||||
|
||||
Hi Werner..
|
||||
|
||||
I was looking at some of the PROJECTS items in the recent gpg CVS and wanted
|
||||
to comment on one of them:
|
||||
|
||||
* Add a way to override the current cipher/md implementations
|
||||
by others (using extensions)
|
||||
|
||||
As you know I've been thinking about how to use a PalmPilot or an iButton in
|
||||
some useful way in GPG. The two things that seem reasonable are:
|
||||
1) keep the secret key in the device, only transferring it to the host
|
||||
computer for the duration of the secret-key operation (sign or decrypt).
|
||||
The key is never kept on disk, only in RAM. This removes the chance that
|
||||
casual snooping on your office workstation will reveal your key (it
|
||||
doesn't help against an active attack, but the attacker must leave a
|
||||
tampered version of GPG around or otherwise get their code to run while
|
||||
the key-storage device is attached to attack the key)
|
||||
2) perform the secret-key operation on the device, so the secret key never
|
||||
leaves the confines of that device. There are still attacks possible,
|
||||
based upon talking to the device while it is connected and trying to
|
||||
convince the device (and possibly the user) that it is the real GPG,
|
||||
but in general this protects the key pretty strongly. Any individual
|
||||
message is still vulnerable, but that's a tradeoff of the convenience of
|
||||
composing that message on a full-sized screen+keyboard (plus the added
|
||||
speed of encryption) vs. the security of writing the message on a
|
||||
secure device.
|
||||
|
||||
I think there are a variety of ways of implementing these things, but a few
|
||||
extension mechanisms in GPG should be enough to try various ways later on.
|
||||
|
||||
1) pass an argument string to loadable extension modules (maybe
|
||||
gpg --load-extension foofish=arg1,arg2,arg3 ?)
|
||||
--> could also be achived by S-Exps
|
||||
|
||||
2) allow multiple instances of the same extension module (presumably with
|
||||
different arguments)
|
||||
--> set an alias name when loading them
|
||||
3) allow extension modules to use stdin/stdout/stderr as normal (probably
|
||||
already in there), for giving feedback to the user, or possibly asking them
|
||||
for a password of some sort
|
||||
--> there should really be some kind of callback mechanism.
|
||||
|
||||
4) have an extension to provide secret keys:
|
||||
|
||||
It looks like most of the hooks for this are already in place, it just
|
||||
needs an extension module which can register itself as a keyblock resource.
|
||||
|
||||
I'm thinking of a module for this that is given an external program name as
|
||||
an argument. When the keyblock resource is asked to enumerate its keys, it
|
||||
runs the external program (first with a "0" argument, then a "1", and so on
|
||||
until the program reports that no more keys are available). The external
|
||||
--> better use a cookie: This way we are also stateless but have a more
|
||||
general interface.
|
||||
|
||||
program returns one (possibly armored) secret key block each time. The
|
||||
program might have some kind of special protocol to talk to the storage
|
||||
device. One thing that comes to mind is to simply include a random number
|
||||
in the message sent over the serial port: the program would display this
|
||||
number, the Pilot at the other end would display the number it receives, if
|
||||
the user sees that both are the same they instruct the Pilot to release the
|
||||
key, as basic protection against someone else asking for the key while it
|
||||
is attached. More sophisticated schemes are possible depending upon how
|
||||
much processing power and IO is available on the device. But the same
|
||||
extension module should be able to handle as complex a scheme as one could
|
||||
wish.
|
||||
--> authenticate the session on startup, using DH and the mentioned
|
||||
cookie/screen/keyboard authentication.
|
||||
|
||||
The current keyblock-resource interface would work fine, although it
|
||||
might be more convenient if a resource could be asked for a key by id
|
||||
instead of enumerating all of them and then searching through the resulting
|
||||
list for a match. A module that provided public keys would have to work this
|
||||
way (imagine a module that could automatically do an http fetch for a
|
||||
particular key.. easily-added automatic key fetching). Without that ability
|
||||
to fetch by id (which would require it to fall back to the other keyblock
|
||||
resources if it failed), the user's device might be asked to release the
|
||||
key even though some other secret key was the one needed.
|
||||
--> Right.
|
||||
|
||||
|
||||
5) have an extension to perform a secret-key operation without the actual
|
||||
secret key material
|
||||
--> Define a clear interface to do this and in the first step write
|
||||
a daemon which does exactly this.
|
||||
|
||||
basically something to indicate that any decrypt or sign operations that
|
||||
occur for a specific keyid should call the extension module instead. The
|
||||
secret key would not be extracted (it wouldn't be available anyway). The
|
||||
module is given the keyid and the MPI of the block it is supposed to sign
|
||||
or decrypt.
|
||||
|
||||
The module could then run an external program to do the operation. I'm
|
||||
imagining a Pilot program which receives the data, asks the user if it can go
|
||||
along with the operation (after displaying a hash of the request, which is
|
||||
also displayed by the extension module's program to make sure the Pilot is
|
||||
being asked to do the right operation), performs the signature or decryption,
|
||||
then returns the data. This protocol could be made arbitrarily complex, with
|
||||
a D-H key to encrypt the link, and both sides signing requests to
|
||||
authenticate one to the other (although this transforms the the problem of
|
||||
getting your secret key off your office workstation into the problem of
|
||||
your workstation holding a key tells your Pilot that it is allowed to perform
|
||||
the secret key operation, and if someone gets a hold of that key they may
|
||||
be able to trick your pilot [plugged in somewhere else] to do the same thing
|
||||
for them).
|
||||
|
||||
This is basically red/black separation, with the Pilot or iButton having the
|
||||
perimeter beyond which the red data doesn't pass. Better than the secret-key
|
||||
storage device but requires a lot more power on the device (the new iButtons
|
||||
with the exponentiator could do it, but it would take way too much code space
|
||||
on the old ones, although they would be fine for just carrying the keys).
|
||||
|
||||
The signature code might need to be extended to verify the signature you just
|
||||
made, since an active intruder pretending to the the Pilot wouldn't be able to
|
||||
make a valid signature (but they might sign your message with a different key
|
||||
just to be annoying).
|
||||
|
||||
Anyway, just wanted to share my thoughts on some possibilities. I've been
|
||||
carrying this little Java iButton on my keyring for months now, looking for
|
||||
something cool to do with it, and I think that secure storage for my GPG key
|
||||
would be just the right application.
|
||||
|
||||
cheers,
|
||||
-Brian
|
||||
|
||||
-----BEGIN PGP SIGNATURE-----
|
||||
Version: GnuPG v0.4.5 (GNU/Linux)
|
||||
Comment: For info finger gcrypt@ftp.guug.de
|
||||
|
||||
iD8DBQE2c5oZkDmgv9E5zEwRArAwAKDWV5fpTtbGPiMPgl2Bpp0gvhbfQgCgzJuY
|
||||
AmIQTk4s62/y2zMAHDdOzK0=
|
||||
=jr7m
|
||||
-----END PGP SIGNATURE-----
|
||||
|
||||
|
||||
|
||||
About a new Keyserver (discussion with Allan Clark <allanc@sco.com>):
|
||||
=====================
|
||||
|
||||
Some ideas:
|
||||
|
||||
o the KS should verify signatures and only accept those
|
||||
which are good.
|
||||
|
||||
o Keep a blacklist of known bad signatures to minimize
|
||||
the time needed to check them
|
||||
|
||||
o Should be fast - I'm currently designing a new storage
|
||||
system called keybox which takes advantage of the fact
|
||||
that the keyID is highly random and can directly be
|
||||
used as a hash value and this keyID is (for v4 keys)
|
||||
part of the fingerprint: So it is possible to use the
|
||||
fingerprint as key but do an lookup by the keyID.
|
||||
|
||||
o To be used as the "public keyring" in a LAN so that there
|
||||
is no need to keep one on every machine.
|
||||
|
||||
o Allow more that one file for key storage.
|
||||
|
||||
o Use the HKS protocol and enhance it in a way that binary
|
||||
keyrings can be transmitted. (I already wrote some
|
||||
http server and client code which can be used for this)
|
||||
And extend it to allow reuse of a connection.
|
||||
|
||||
o Keep a checksum (hash) of the entire keyblock so that a
|
||||
client can easy check whether this keyblock has changed.
|
||||
(keyblock = the entire key with all certificates etc.)
|
||||
Transmitted in the HEAD info.
|
||||
|
||||
o Allow efficient propagation of new keys and revocation
|
||||
certificates.
|
||||
|
||||
|
||||
Probably more things but this keyserver is not a goal for the
|
||||
1.0 release. Someone should be able to fix some of the limitations
|
||||
of the existing key servers (I think they bail out on some rfc2440
|
||||
packet formats).
|
||||
|
||||
|
||||
DJGPP
|
||||
=====
|
||||
Don't use symlinks but try to do the preprocessing in the config-links script.
|
||||
DJPGG has problems to distinguish betwen .s and .S becaus the FAT filesystem
|
||||
is not case sensitive (Mark Elbrecht).
|
||||
Well, it runs only on one architecture and therefor it might be possible
|
||||
to add a special case for it, completely bypassing the symlink autselection
|
||||
trick.
|
||||
|
||||
Special procmail addresses
|
||||
==========================
|
||||
* foo+bar@example.net: Try to match the address without the "+bar".
|
||||
Should be done by the MUA, but maybe we can do this.
|
||||
--> Yep. Another reason to utilize a directory service or something
|
||||
else for keylookup.
|
||||
|
||||
|
||||
|
||||
Suggested things which I will not do:
|
||||
=====================================
|
||||
* Let take --help an option to select some topics.
|
||||
Using grep is much easier
|
||||
* Check if an object (a message, detached sign, public key, or whatever)
|
||||
is signed by definite user, i.e. define user
|
||||
(userid, or any other unique identification) on command line.
|
||||
--> Use a script and --status-fd
|
||||
|
||||
|
||||
Copyright 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
|
||||
|
||||
This file is free software; as a special exception the author gives
|
||||
unlimited permission to copy and/or distribute it, with or without
|
||||
modifications, as long as this notice is preserved.
|
||||
|
||||
This file is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
|
||||
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
149
TODO
@ -1,72 +1,121 @@
|
||||
* Using an expired key for signing should give an error message
|
||||
"expired key" and not "unusable key'. Furthermore the error should
|
||||
also be thrown when the default key has expired. Reported by
|
||||
Eric.VanBuggenhaut add AdValvas.be.
|
||||
-*- outline -*-
|
||||
|
||||
* pause scrolling help in --edit-key and elsewhere.
|
||||
* src/base64
|
||||
** Make parsing more robust
|
||||
Currently we don't cope with overlong lines in the best way.
|
||||
** Check that we really release the ksba reader/writer objects.
|
||||
|
||||
* getkey does not return revoked/expired keys - therefore it is not
|
||||
possible to override it.
|
||||
* sm/call-agent.c
|
||||
** The protocol uses an incomplete S-expression
|
||||
We should always use valid S-Exp and not just parts.
|
||||
** Some code should go into import.c
|
||||
** When we allow concurrent service request in gpgsm, we
|
||||
might want to have an agent context for each service request
|
||||
(i.e. Assuan context).
|
||||
|
||||
* Selection using +wordlist does not work.
|
||||
What about adding a feature -word to the +wordlist search mode.
|
||||
* sm/certchain.c
|
||||
** When a certificate chain was sucessfully verified, make ephemeral certs used in this chain permanent.
|
||||
** Try to keep certificate references somewhere
|
||||
This will help with some of our caching code. We also need to test
|
||||
that caching; in particular "regtp_ca_chainlen".
|
||||
|
||||
* Check the changes to the gpg random gatherer on all W32 platforms.
|
||||
* sm/decrypt.c
|
||||
** replace leading zero in integer hack by a cleaner solution
|
||||
|
||||
* Show more info does not work from edit->trust. We should give more
|
||||
information on the user ID under question while running
|
||||
--update-trustdb.
|
||||
* sm/gpgsm.c
|
||||
** Support --output for all commands
|
||||
** mark all unimplemented commands and options.
|
||||
** Implement --default-key
|
||||
** support the anyPolicy semantic
|
||||
** Check that we are really following the verification procedures in rfc3280.
|
||||
** Implement a --card-status command.
|
||||
This is useful to check whether a card is supported at all.
|
||||
|
||||
* Check that no secret temporary results are stored in the result parameter
|
||||
of the mpi functions. We have already done this for mpi-mul.c
|
||||
|
||||
* We need another special packet at the end of a clearsign message to mark
|
||||
it's end and allow for multiple signature for one message. And
|
||||
add a real grammar to the code in mainproc.c
|
||||
* sm/keydb.c
|
||||
** Check file permissions
|
||||
** Check that all error code mapping is done.
|
||||
** Remove the inter-module dependencies between gpgsm and keybox
|
||||
** Add an source_of_key field
|
||||
|
||||
* Fix the bug in the mips assembler code
|
||||
* agent/command.c
|
||||
** Make sure that secure memory is used where appropriate
|
||||
|
||||
* Add a way to show the fingerprint of an key signator's keys
|
||||
* agent/pkdecrypt.c, agent/pksign.c
|
||||
** Don't use stdio to return results.
|
||||
** Support DSA
|
||||
|
||||
* Concatenated encryption messages don't work corectly - only the
|
||||
first one is processed.
|
||||
* Move pkcs-1 encoding into libgcrypt.
|
||||
|
||||
* Add option to put the list of recipients (from the encryption
|
||||
layer) into the signatures notation data.
|
||||
* Use a MAC to protect sensitive files.
|
||||
The problem here is that we need yet another key and it is unlikely
|
||||
that users are willing to remember that key too. It is possible to
|
||||
do this with a smartcard, though.
|
||||
|
||||
* --disable-asm should still assemble _udiv_qrnnd when needed
|
||||
* sm/export.c
|
||||
** Return an error code or a status info per user ID.
|
||||
|
||||
* the pubkey encrypt functions should do some sanity checks.
|
||||
* scd/tlv.c
|
||||
The parse_sexp fucntion should not go into this file. Check whether
|
||||
we can change all S-expression handling code to make use of this
|
||||
function.
|
||||
|
||||
* "gpg filename.tar.gz.asc" should work like --verify (-sab).
|
||||
* scd
|
||||
** Application context vs. reader slot
|
||||
We have 2 concurrent method of tracking whether a read is in use:
|
||||
Using the session_list in command.c and the lock_table in app.c. IT
|
||||
would be better to do this just at one place. First we need to see
|
||||
how we can support cards with multiple applications.
|
||||
** Detecting a removed card works only after the ticker detected it.
|
||||
We should check the card status in open-card to make this smoother.
|
||||
Needs to be integrated with the status file update, though. It is
|
||||
not a real problem because application will get a card removed status
|
||||
and should the send a reset to try solving the problem.
|
||||
|
||||
* for messages created with "-t", it might make sense to append the
|
||||
verification status of the message to the output (i.e. write something to
|
||||
the --output file and not only to stderr. However the problem is
|
||||
that we consider the message transpatrent and don't have any
|
||||
indication of the used character set. To implement this feature
|
||||
we need to make sure that all output is plain 7 bit ascii but
|
||||
given that we need to print a user name, this does not make sense
|
||||
at all. The only way this can be implemented is by assuming that
|
||||
the message is encoded in utf8 and hope tht everyone starts to use
|
||||
utf8 instead of latin-1 or whatever RSN. Hmmm, I myself should
|
||||
start with this.
|
||||
* tests
|
||||
** Makefile.am
|
||||
We use printf(1) to setup the library path, this is not portable.
|
||||
Furthermore LD_LIBRARY_PATH is not used on all systems. It doesn't
|
||||
matter for now, because we use some GNU/*BSDish features anyway.
|
||||
|
||||
* keyflags don't distinguish between {certify,signature}-only.
|
||||
** Add a test to check the extkeyusage.
|
||||
|
||||
* cat foo | gpg --sign | gpg --list-packets
|
||||
Does not list the signature packet.
|
||||
* doc/
|
||||
** Explain how to setup a root CA key as trusted
|
||||
** Explain how trustlist.txt might be managed.
|
||||
** Write a script to generate man pages from texi.
|
||||
In progress (yatm)
|
||||
|
||||
* When presenting the result of a verification show the user ID with
|
||||
the highest trust level first instead of the primary one.
|
||||
|
||||
* allow the use of option in gpg.conf.
|
||||
* Windows port
|
||||
** gpgsm's LISTKEYS does not yet work
|
||||
Fix is to change everything to libestream
|
||||
** Signals are not support
|
||||
This means we can't reread a configuration
|
||||
** No card status notifications.
|
||||
|
||||
* Add the NEWSIG status.
|
||||
|
||||
* Delete a card key as well as a wiping.
|
||||
|
||||
* passphrase_to_dek does not return NULL after a cancel. There is
|
||||
no way to issue a cancel when unsing the CLI - this would however
|
||||
be a Good Thing when used with mixed symkey/pubkey encrypted
|
||||
messages. See comment in mainproc.c:proc_symkey_enc.
|
||||
* sm/
|
||||
** check that we issue NO_SECKEY xxx if a -u key was not found
|
||||
|
||||
* jnlib/
|
||||
** provide jnlib_malloc and try to remove all jnlib_xmalloc.
|
||||
|
||||
* gpg/
|
||||
** issue a NO_SECKEY xxxx if a -u key was not found.
|
||||
** Replace DIGEST_ALGO_SHA224
|
||||
We can't do that right now because it is only defined by newer
|
||||
versions of libgcrypt. Changes this if we require libgcrypt 1.3
|
||||
anyway.
|
||||
** skclist.c:random_is_faked
|
||||
Remove the whole stuff?
|
||||
** qbits
|
||||
We pass a new qbit parameter to genkey - implement this in libgcrypt.
|
||||
|
||||
|
||||
* common/
|
||||
** ttyio
|
||||
Add completion support.
|
||||
** yesno
|
||||
Update to gpg 1.4.3 version
|
||||
|
579
acinclude.m4
@ -15,15 +15,7 @@ dnl GNU General Public License for more details.
|
||||
dnl
|
||||
dnl You should have received a copy of the GNU General Public License
|
||||
dnl along with this program; if not, write to the Free Software
|
||||
dnl Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
|
||||
dnl GNUPG_MSG_PRINT(STRING)
|
||||
dnl print a message
|
||||
dnl
|
||||
define(GNUPG_MSG_PRINT,
|
||||
[ echo $ac_n "$1"" $ac_c" 1>&AC_FD_MSG
|
||||
])
|
||||
|
||||
dnl Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
|
||||
dnl GNUPG_CHECK_TYPEDEF(TYPE, HAVE_NAME)
|
||||
dnl Check whether a typedef exists and create a #define $2 if it exists
|
||||
@ -61,7 +53,6 @@ AC_DEFUN([GNUPG_CHECK_GNUMAKE],
|
||||
fi
|
||||
])
|
||||
|
||||
|
||||
dnl GNUPG_CHECK_FAQPROG
|
||||
dnl
|
||||
AC_DEFUN([GNUPG_CHECK_FAQPROG],
|
||||
@ -106,10 +97,11 @@ AC_DEFUN([GNUPG_CHECK_DOCBOOK_TO_TEXI],
|
||||
])
|
||||
|
||||
|
||||
|
||||
dnl GNUPG_CHECK_ENDIAN
|
||||
dnl define either LITTLE_ENDIAN_HOST or BIG_ENDIAN_HOST
|
||||
dnl
|
||||
define([GNUPG_CHECK_ENDIAN],
|
||||
AC_DEFUN([GNUPG_CHECK_ENDIAN],
|
||||
[
|
||||
tmp_assumed_endian=big
|
||||
if test "$cross_compiling" = yes; then
|
||||
@ -163,213 +155,128 @@ define([GNUPG_CHECK_ENDIAN],
|
||||
fi
|
||||
])
|
||||
|
||||
dnl GNUPG_CHECK_CACHE
|
||||
dnl
|
||||
define(GNUPG_CHECK_CACHE,
|
||||
[ AC_MSG_CHECKING(cached information)
|
||||
gnupg_hostcheck="$target"
|
||||
AC_CACHE_VAL(gnupg_cv_hostcheck, [ gnupg_cv_hostcheck="$gnupg_hostcheck" ])
|
||||
if test "$gnupg_cv_hostcheck" != "$gnupg_hostcheck"; then
|
||||
AC_MSG_RESULT(changed)
|
||||
AC_MSG_WARN(config.cache exists!)
|
||||
AC_MSG_ERROR(you must do 'make distclean' first to compile for
|
||||
different target or different parameters.)
|
||||
else
|
||||
AC_MSG_RESULT(ok)
|
||||
|
||||
|
||||
# Check for the getsockopt SO_PEERCRED
|
||||
AC_DEFUN([GNUPG_SYS_SO_PEERCRED],
|
||||
[ AC_MSG_CHECKING(for SO_PEERCRED)
|
||||
AC_CACHE_VAL(gnupg_cv_sys_so_peercred,
|
||||
[AC_TRY_COMPILE([#include <sys/socket.h>],
|
||||
[struct ucred cr;
|
||||
int cl = sizeof cr;
|
||||
getsockopt (1, SOL_SOCKET, SO_PEERCRED, &cr, &cl);],
|
||||
gnupg_cv_sys_so_peercred=yes,
|
||||
gnupg_cv_sys_so_peercred=no)
|
||||
])
|
||||
AC_MSG_RESULT($gnupg_cv_sys_so_peercred)
|
||||
if test $gnupg_cv_sys_so_peercred = yes; then
|
||||
AC_DEFINE(HAVE_SO_PEERCRED, 1,
|
||||
[Defined if SO_PEERCRED is supported (Linux)])
|
||||
fi
|
||||
])
|
||||
|
||||
|
||||
######################################################################
|
||||
# Check for -fPIC etc (taken from libtool)
|
||||
# This sets CFLAGS_PIC to the required flags
|
||||
# NO_PIC to yes if it is not possible to
|
||||
# generate PIC
|
||||
######################################################################
|
||||
dnl GNUPG_CHECK_PIC
|
||||
dnl
|
||||
define(GNUPG_CHECK_PIC,
|
||||
[ AC_MSG_CHECKING(for option to create PIC)
|
||||
CFLAGS_PIC=
|
||||
NO_PIC=no
|
||||
if test "$cross_compiling" = yes; then
|
||||
AC_MSG_RESULT(assume none)
|
||||
else
|
||||
if test "$GCC" = yes; then
|
||||
CFLAGS_PIC="-fPIC"
|
||||
else
|
||||
case "$host_os" in
|
||||
aix3* | aix4*)
|
||||
# All rs/6000 code is PIC
|
||||
# but is there any non-rs/6000 AIX platform?
|
||||
;;
|
||||
|
||||
hpux9* | hpux10*)
|
||||
CFLAGS_PIC="+Z"
|
||||
;;
|
||||
# GNUPG_BUILD_PROGRAM(NAME,DEFAULT)
|
||||
# Add a --enable-NAME option to configure an set the
|
||||
# shell variable build_NAME either to "yes" or "no". DEFAULT must
|
||||
# either be "yes" or "no" and decided on the default value for
|
||||
# build_NAME and whether --enable-NAME or --disable-NAME is shown with
|
||||
# ./configure --help
|
||||
AC_DEFUN([GNUPG_BUILD_PROGRAM],
|
||||
[build_$1=$2
|
||||
m4_if([$2],[yes],[
|
||||
AC_ARG_ENABLE([$1], AC_HELP_STRING([--disable-$1],
|
||||
[do not build the $1 program]),
|
||||
build_$1=$enableval, build_$1=$2)
|
||||
],[
|
||||
AC_ARG_ENABLE([$1], AC_HELP_STRING([--enable-$1],
|
||||
[build the $1 program]),
|
||||
build_$1=$enableval, build_$1=$2)
|
||||
])
|
||||
case "$build_$1" in
|
||||
no|yes)
|
||||
;;
|
||||
*)
|
||||
AC_MSG_ERROR([only yes or no allowed for feature --enable-$1])
|
||||
;;
|
||||
esac
|
||||
])
|
||||
|
||||
irix5* | irix6*)
|
||||
# PIC (with -KPIC) is the default.
|
||||
;;
|
||||
|
||||
osf3* | osf4*)
|
||||
# FIXME - pic_flag is probably required for
|
||||
# hppa*-osf* and i860-osf*
|
||||
;;
|
||||
|
||||
sco3.2v5*)
|
||||
CFLAGS_PIC='-Kpic'
|
||||
;;
|
||||
# GNUPG_PTH_VERSION_CHECK(REQUIRED)
|
||||
#
|
||||
# If the version is sufficient, HAVE_PTH will be set to yes.
|
||||
#
|
||||
# Taken form the m4 macros which come with Pth
|
||||
AC_DEFUN([GNUPG_PTH_VERSION_CHECK],
|
||||
[
|
||||
_pth_version=`$PTH_CONFIG --version | awk 'NR==1 {print [$]3}'`
|
||||
_req_version="ifelse([$1],,1.2.0,$1)"
|
||||
|
||||
solaris2* | solaris7* )
|
||||
CFLAGS_PIC='-KPIC'
|
||||
;;
|
||||
|
||||
sunos4*)
|
||||
CFLAGS_PIC='-PIC'
|
||||
;;
|
||||
|
||||
*)
|
||||
NO_PIC=yes
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
|
||||
case "$host_cpu" in
|
||||
rs6000 | powerpc | powerpcle)
|
||||
# Yippee! All RS/6000 and PowerPC code is position-independent.
|
||||
CFLAGS_PIC=""
|
||||
;;
|
||||
AC_MSG_CHECKING(for PTH - version >= $_req_version)
|
||||
for _var in _pth_version _req_version; do
|
||||
eval "_val=\"\$${_var}\""
|
||||
_major=`echo $_val | sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\([[ab.]]\)\([[0-9]]*\)/\1/'`
|
||||
_minor=`echo $_val | sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\([[ab.]]\)\([[0-9]]*\)/\2/'`
|
||||
_rtype=`echo $_val | sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\([[ab.]]\)\([[0-9]]*\)/\3/'`
|
||||
_micro=`echo $_val | sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\([[ab.]]\)\([[0-9]]*\)/\4/'`
|
||||
case $_rtype in
|
||||
"a" ) _rtype=0 ;;
|
||||
"b" ) _rtype=1 ;;
|
||||
"." ) _rtype=2 ;;
|
||||
esac
|
||||
|
||||
if test "$NO_PIC" = yes; then
|
||||
AC_MSG_RESULT(not possible)
|
||||
else
|
||||
if test -z "$CFLAGS_PIC"; then
|
||||
AC_MSG_RESULT(none)
|
||||
else
|
||||
AC_MSG_RESULT($CFLAGS_PIC)
|
||||
_hex=`echo dummy | awk '{ printf("%d%02d%1d%02d", major, minor, rtype, micro); }' \
|
||||
"major=$_major" "minor=$_minor" "rtype=$_rtype" "micro=$_micro"`
|
||||
eval "${_var}_hex=\"\$_hex\""
|
||||
done
|
||||
have_pth=no
|
||||
if test ".$_pth_version_hex" != .; then
|
||||
if test ".$_req_version_hex" != .; then
|
||||
if test $_pth_version_hex -ge $_req_version_hex; then
|
||||
have_pth=yes
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
])
|
||||
|
||||
|
||||
######################################################################
|
||||
# Check for export-dynamic flag
|
||||
# This sets CFLAGS_EXPORTDYNAMIC to the required flags
|
||||
######################################################################
|
||||
dnl GNUPG_CHECK_EXPORTDYNAMIC
|
||||
dnl
|
||||
define(GNUPG_CHECK_EXPORTDYNAMIC,
|
||||
[ AC_MSG_CHECKING(how to specify -export-dynamic)
|
||||
if test "$cross_compiling" = yes; then
|
||||
AC_MSG_RESULT(assume none)
|
||||
CFLAGS_EXPORTDYNAMIC=""
|
||||
if test $have_pth = yes; then
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_MSG_CHECKING([whether PTH installation is sane])
|
||||
AC_CACHE_VAL(gnupg_cv_pth_is_sane,[
|
||||
_gnupg_pth_save_cflags=$CFLAGS
|
||||
_gnupg_pth_save_ldflags=$LDFLAGS
|
||||
_gnupg_pth_save_libs=$LIBS
|
||||
CFLAGS="$CFLAGS `$PTH_CONFIG --cflags`"
|
||||
LDFLAGS="$LDFLAGS `$PTH_CONFIG --ldflags`"
|
||||
LIBS="$LIBS `$PTH_CONFIG --libs`"
|
||||
AC_LINK_IFELSE([AC_LANG_PROGRAM([#include <pth.h>
|
||||
],
|
||||
[[ pth_init ();]])],
|
||||
gnupg_cv_pth_is_sane=yes,
|
||||
gnupg_cv_pth_is_sane=no)
|
||||
CFLAGS=$_gnupg_pth_save_cflags
|
||||
LDFLAGS=$_gnupg_pth_save_ldflags
|
||||
LIBS=$_gnupg_pth_save_libs
|
||||
])
|
||||
if test $gnupg_cv_pth_is_sane != yes; then
|
||||
have_pth=no
|
||||
fi
|
||||
AC_MSG_RESULT($gnupg_cv_pth_is_sane)
|
||||
else
|
||||
AC_CACHE_VAL(gnupg_cv_export_dynamic,[
|
||||
if AC_TRY_COMMAND([${CC-cc} $CFLAGS -Wl,--version 2>&1 |
|
||||
grep "GNU ld" >/dev/null]); then
|
||||
# using gnu's linker
|
||||
gnupg_cv_export_dynamic="-Wl,-export-dynamic"
|
||||
else
|
||||
case "$host_os" in
|
||||
hpux* )
|
||||
gnupg_cv_export_dynamic="-Wl,-E"
|
||||
;;
|
||||
* )
|
||||
gnupg_cv_export_dynamic=""
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
])
|
||||
AC_MSG_RESULT($gnupg_cv_export_dynamic)
|
||||
CFLAGS_EXPORTDYNAMIC="$gnupg_cv_export_dynamic"
|
||||
fi
|
||||
AC_MSG_RESULT(no)
|
||||
fi
|
||||
])
|
||||
|
||||
#####################################################################
|
||||
# Check for SysV IPC (from GIMP)
|
||||
# And see whether we have a SHM_LOCK (FreeBSD does not have it).
|
||||
#####################################################################
|
||||
dnl GNUPG_CHECK_IPC
|
||||
dnl
|
||||
define(GNUPG_CHECK_IPC,
|
||||
[ AC_CHECK_HEADERS(sys/ipc.h sys/shm.h)
|
||||
if test "$ac_cv_header_sys_shm_h" = "yes"; then
|
||||
AC_MSG_CHECKING(whether IPC_RMID allowes subsequent attaches)
|
||||
AC_CACHE_VAL(gnupg_cv_ipc_rmid_deferred_release,
|
||||
AC_TRY_RUN([
|
||||
#include <sys/types.h>
|
||||
#include <sys/ipc.h>
|
||||
#include <sys/shm.h>
|
||||
int main()
|
||||
{
|
||||
int id;
|
||||
char *shmaddr;
|
||||
id = shmget (IPC_PRIVATE, 4, IPC_CREAT | 0777);
|
||||
if (id == -1)
|
||||
exit (2);
|
||||
shmaddr = shmat (id, 0, 0);
|
||||
shmctl (id, IPC_RMID, 0);
|
||||
if ((char*) shmat (id, 0, 0) == (char*) -1)
|
||||
{
|
||||
shmdt (shmaddr);
|
||||
exit (1);
|
||||
}
|
||||
shmdt (shmaddr);
|
||||
shmdt (shmaddr);
|
||||
exit (0);
|
||||
}
|
||||
],
|
||||
gnupg_cv_ipc_rmid_deferred_release="yes",
|
||||
gnupg_cv_ipc_rmid_deferred_release="no",
|
||||
gnupg_cv_ipc_rmid_deferred_release="assume-no")
|
||||
)
|
||||
if test "$gnupg_cv_ipc_rmid_deferred_release" = "yes"; then
|
||||
AC_DEFINE(IPC_RMID_DEFERRED_RELEASE,1,
|
||||
[Defined if we can do a deferred shm release])
|
||||
AC_MSG_RESULT(yes)
|
||||
else
|
||||
if test "$gnupg_cv_ipc_rmid_deferred_release" = "no"; then
|
||||
AC_MSG_RESULT(no)
|
||||
else
|
||||
AC_MSG_RESULT([assuming no])
|
||||
fi
|
||||
fi
|
||||
|
||||
AC_MSG_CHECKING(whether SHM_LOCK is available)
|
||||
AC_CACHE_VAL(gnupg_cv_ipc_have_shm_lock,
|
||||
AC_TRY_COMPILE([#include <sys/types.h>
|
||||
#include <sys/ipc.h>
|
||||
#include <sys/shm.h>],[
|
||||
int shm_id;
|
||||
shmctl(shm_id, SHM_LOCK, 0);
|
||||
],
|
||||
gnupg_cv_ipc_have_shm_lock="yes",
|
||||
gnupg_cv_ipc_have_shm_lock="no"
|
||||
)
|
||||
)
|
||||
if test "$gnupg_cv_ipc_have_shm_lock" = "yes"; then
|
||||
AC_DEFINE(IPC_HAVE_SHM_LOCK,1,
|
||||
[Defined if a SysV shared memory supports the LOCK flag])
|
||||
AC_MSG_RESULT(yes)
|
||||
else
|
||||
AC_MSG_RESULT(no)
|
||||
fi
|
||||
fi
|
||||
])
|
||||
|
||||
|
||||
######################################################################
|
||||
|
||||
# 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_DEFUN([GNUPG_CHECK_MLOCK],
|
||||
[ AC_CHECK_FUNCS(mlock)
|
||||
if test "$ac_cv_func_mlock" = "no"; then
|
||||
AC_CHECK_HEADERS(sys/mman.h)
|
||||
@ -456,274 +363,6 @@ define(GNUPG_CHECK_MLOCK,
|
||||
])
|
||||
|
||||
|
||||
################################################################
|
||||
# GNUPG_PROG_NM - find the path to a BSD-compatible name lister
|
||||
AC_DEFUN([GNUPG_PROG_NM],
|
||||
[AC_MSG_CHECKING([for BSD-compatible nm])
|
||||
AC_CACHE_VAL(ac_cv_path_NM,
|
||||
[if test -n "$NM"; then
|
||||
# Let the user override the test.
|
||||
ac_cv_path_NM="$NM"
|
||||
else
|
||||
IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
|
||||
for ac_dir in /usr/ucb /usr/ccs/bin $PATH /bin; do
|
||||
test -z "$ac_dir" && ac_dir=.
|
||||
if test -f $ac_dir/nm; then
|
||||
# Check to see if the nm accepts a BSD-compat flag.
|
||||
# Adding the `sed 1q' prevents false positives on HP-UX, which says:
|
||||
# nm: unknown option "B" ignored
|
||||
if ($ac_dir/nm -B /dev/null 2>&1 | sed '1q'; exit 0) | egrep /dev/null >/dev/null; then
|
||||
ac_cv_path_NM="$ac_dir/nm -B"
|
||||
elif ($ac_dir/nm -p /dev/null 2>&1 | sed '1q'; exit 0) | egrep /dev/null >/dev/null; then
|
||||
ac_cv_path_NM="$ac_dir/nm -p"
|
||||
else
|
||||
ac_cv_path_NM="$ac_dir/nm"
|
||||
fi
|
||||
break
|
||||
fi
|
||||
done
|
||||
IFS="$ac_save_ifs"
|
||||
test -z "$ac_cv_path_NM" && ac_cv_path_NM=nm
|
||||
fi])
|
||||
NM="$ac_cv_path_NM"
|
||||
AC_MSG_RESULT([$NM])
|
||||
AC_SUBST(NM)
|
||||
])
|
||||
|
||||
# GNUPG_SYS_NM_PARSE - Check for command ro grab the raw symbol name followed
|
||||
# by C symbol name from nm.
|
||||
AC_DEFUN([GNUPG_SYS_NM_PARSE],
|
||||
[AC_REQUIRE([AC_CANONICAL_HOST])dnl
|
||||
AC_REQUIRE([GNUPG_PROG_NM])dnl
|
||||
# Check for command to grab the raw symbol name followed by C symbol from nm.
|
||||
AC_MSG_CHECKING([command to parse $NM output])
|
||||
AC_CACHE_VAL(ac_cv_sys_global_symbol_pipe,
|
||||
[# These are sane defaults that work on at least a few old systems.
|
||||
# {They come from Ultrix. What could be older than Ultrix?!! ;)}
|
||||
|
||||
changequote(,)dnl
|
||||
# Character class describing NM global symbol codes.
|
||||
ac_symcode='[BCDEGRSTU]'
|
||||
|
||||
# Regexp to match symbols that can be accessed directly from C.
|
||||
ac_sympat='\([_A-Za-z][_A-Za-z0-9]*\)'
|
||||
|
||||
# Transform the above into a raw symbol and a C symbol.
|
||||
ac_symxfrm='\1 \1'
|
||||
|
||||
# Define system-specific variables.
|
||||
case "$host_os" in
|
||||
aix*)
|
||||
ac_symcode='[BCDTU]'
|
||||
;;
|
||||
freebsd* | netbsd* | openbsd* | bsdi* | sunos* | cygwin32* | mingw32*)
|
||||
ac_sympat='_\([_A-Za-z][_A-Za-z0-9]*\)'
|
||||
ac_symxfrm='_\1 \1'
|
||||
;;
|
||||
irix*)
|
||||
# Cannot use undefined symbols on IRIX because inlined functions mess us up.
|
||||
ac_symcode='[BCDEGRST]'
|
||||
;;
|
||||
solaris*)
|
||||
ac_symcode='[BDTU]'
|
||||
;;
|
||||
esac
|
||||
|
||||
# If we're using GNU nm, then use its standard symbol codes.
|
||||
if $NM -V 2>&1 | egrep '(GNU|with BFD)' > /dev/null; then
|
||||
ac_symcode='[ABCDGISTUW]'
|
||||
fi
|
||||
|
||||
case "$host_os" in
|
||||
cygwin32* | mingw32*)
|
||||
# We do not want undefined symbols on cygwin32. The user must
|
||||
# arrange to define them via -l arguments.
|
||||
ac_symcode='[ABCDGISTW]'
|
||||
;;
|
||||
esac
|
||||
changequote([,])dnl
|
||||
|
||||
# Write the raw and C identifiers.
|
||||
ac_cv_sys_global_symbol_pipe="sed -n -e 's/^.* $ac_symcode $ac_sympat$/$ac_symxfrm/p'"
|
||||
|
||||
# Check to see that the pipe works correctly.
|
||||
ac_pipe_works=no
|
||||
cat > conftest.$ac_ext <<EOF
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
char nm_test_var;
|
||||
void nm_test_func(){}
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
int main(){nm_test_var='a';nm_test_func;return 0;}
|
||||
EOF
|
||||
if AC_TRY_EVAL(ac_compile); then
|
||||
# Now try to grab the symbols.
|
||||
ac_nlist=conftest.nm
|
||||
if AC_TRY_EVAL(NM conftest.$ac_objext \| $ac_cv_sys_global_symbol_pipe \> $ac_nlist) && test -s "$ac_nlist"; then
|
||||
|
||||
# Try sorting and uniquifying the output.
|
||||
if sort "$ac_nlist" | uniq > "$ac_nlist"T; then
|
||||
mv -f "$ac_nlist"T "$ac_nlist"
|
||||
ac_wcout=`wc "$ac_nlist" 2>/dev/null`
|
||||
changequote(,)dnl
|
||||
ac_count=`echo "X$ac_wcout" | sed -e 's,^X,,' -e 's/^[ ]*\([0-9][0-9]*\).*$/\1/'`
|
||||
changequote([,])dnl
|
||||
(test "$ac_count" -ge 0) 2>/dev/null || ac_count=-1
|
||||
else
|
||||
rm -f "$ac_nlist"T
|
||||
ac_count=-1
|
||||
fi
|
||||
|
||||
# Make sure that we snagged all the symbols we need.
|
||||
if egrep ' _?nm_test_var$' "$ac_nlist" >/dev/null; then
|
||||
if egrep ' _?nm_test_func$' "$ac_nlist" >/dev/null; then
|
||||
cat <<EOF > conftest.c
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
EOF
|
||||
# Now generate the symbol file.
|
||||
sed 's/^.* _\{0,1\}\(.*\)$/extern char \1;/' < "$ac_nlist" >> conftest.c
|
||||
|
||||
cat <<EOF >> conftest.c
|
||||
#if defined (__STDC__) && __STDC__
|
||||
# define __ptr_t void *
|
||||
#else
|
||||
# define __ptr_t char *
|
||||
#endif
|
||||
|
||||
/* The number of symbols in dld_preloaded_symbols, -1 if unsorted. */
|
||||
int dld_preloaded_symbol_count = $ac_count;
|
||||
|
||||
/* The mapping between symbol names and symbols. */
|
||||
struct {
|
||||
char *name;
|
||||
__ptr_t address;
|
||||
}
|
||||
changequote(,)dnl
|
||||
dld_preloaded_symbols[] =
|
||||
changequote([,])dnl
|
||||
{
|
||||
EOF
|
||||
sed 's/^_\{0,1\}\(.*\) _\{0,1\}\(.*\)$/ {"\1", (__ptr_t) \&\2},/' < "$ac_nlist" >> conftest.c
|
||||
cat <<\EOF >> conftest.c
|
||||
{0, (__ptr_t) 0}
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
EOF
|
||||
# Now try linking the two files.
|
||||
mv conftest.$ac_objext conftestm.$ac_objext
|
||||
ac_save_LIBS="$LIBS"
|
||||
ac_save_CFLAGS="$CFLAGS"
|
||||
LIBS="conftestm.$ac_objext"
|
||||
CFLAGS="$CFLAGS$no_builtin_flag"
|
||||
if AC_TRY_EVAL(ac_link) && test -s conftest; then
|
||||
ac_pipe_works=yes
|
||||
else
|
||||
echo "configure: failed program was:" >&AC_FD_CC
|
||||
cat conftest.c >&AC_FD_CC
|
||||
fi
|
||||
LIBS="$ac_save_LIBS"
|
||||
CFLAGS="$ac_save_CFLAGS"
|
||||
else
|
||||
echo "cannot find nm_test_func in $ac_nlist" >&AC_FD_CC
|
||||
fi
|
||||
else
|
||||
echo "cannot find nm_test_var in $ac_nlist" >&AC_FD_CC
|
||||
fi
|
||||
else
|
||||
echo "cannot run $ac_cv_sys_global_symbol_pipe" >&AC_FD_CC
|
||||
fi
|
||||
else
|
||||
echo "$progname: failed program was:" >&AC_FD_CC
|
||||
cat conftest.c >&AC_FD_CC
|
||||
fi
|
||||
rm -rf conftest*
|
||||
|
||||
# Do not use the global_symbol_pipe unless it works.
|
||||
test "$ac_pipe_works" = yes || ac_cv_sys_global_symbol_pipe=
|
||||
])
|
||||
|
||||
ac_result=yes
|
||||
if test -z "$ac_cv_sys_global_symbol_pipe"; then
|
||||
ac_result=no
|
||||
fi
|
||||
AC_MSG_RESULT($ac_result)
|
||||
])
|
||||
|
||||
# GNUPG_SYS_LIBTOOL_CYGWIN32 - find tools needed on cygwin32
|
||||
AC_DEFUN([GNUPG_SYS_LIBTOOL_CYGWIN32],
|
||||
[AC_CHECK_TOOL(DLLTOOL, dlltool, false)
|
||||
AC_CHECK_TOOL(AS, as, false)
|
||||
])
|
||||
|
||||
# GNUPG_SYS_SYMBOL_UNDERSCORE - does the compiler prefix global symbols
|
||||
# with an underscore?
|
||||
AC_DEFUN([GNUPG_SYS_SYMBOL_UNDERSCORE],
|
||||
[tmp_do_check="no"
|
||||
case "${target}" in
|
||||
i386-emx-os2 | i[3456]86-pc-os2*emx | i386-pc-msdosdjgpp)
|
||||
ac_cv_sys_symbol_underscore=yes
|
||||
;;
|
||||
*)
|
||||
if test "$cross_compiling" = yes; then
|
||||
ac_cv_sys_symbol_underscore=yes
|
||||
else
|
||||
tmp_do_check="yes"
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
|
||||
if test "$tmp_do_check" = "yes"; then
|
||||
AC_REQUIRE([GNUPG_PROG_NM])dnl
|
||||
AC_REQUIRE([GNUPG_SYS_NM_PARSE])dnl
|
||||
AC_MSG_CHECKING([for _ prefix in compiled symbols])
|
||||
AC_CACHE_VAL(ac_cv_sys_symbol_underscore,
|
||||
[ac_cv_sys_symbol_underscore=no
|
||||
cat > conftest.$ac_ext <<EOF
|
||||
void nm_test_func(){}
|
||||
int main(){nm_test_func;return 0;}
|
||||
EOF
|
||||
if AC_TRY_EVAL(ac_compile); then
|
||||
# Now try to grab the symbols.
|
||||
ac_nlist=conftest.nm
|
||||
if AC_TRY_EVAL(NM conftest.$ac_objext \| $ac_cv_sys_global_symbol_pipe \> $ac_nlist) && test -s "$ac_nlist"; then
|
||||
# See whether the symbols have a leading underscore.
|
||||
if egrep '^_nm_test_func' "$ac_nlist" >/dev/null; then
|
||||
ac_cv_sys_symbol_underscore=yes
|
||||
else
|
||||
if egrep '^nm_test_func ' "$ac_nlist" >/dev/null; then
|
||||
:
|
||||
else
|
||||
echo "configure: cannot find nm_test_func in $ac_nlist" >&AC_FD_CC
|
||||
fi
|
||||
fi
|
||||
else
|
||||
echo "configure: cannot run $ac_cv_sys_global_symbol_pipe" >&AC_FD_CC
|
||||
fi
|
||||
else
|
||||
echo "configure: failed program was:" >&AC_FD_CC
|
||||
cat conftest.c >&AC_FD_CC
|
||||
fi
|
||||
rm -rf conftest*
|
||||
])
|
||||
else
|
||||
AC_MSG_CHECKING([for _ prefix in compiled symbols])
|
||||
fi
|
||||
AC_MSG_RESULT($ac_cv_sys_symbol_underscore)
|
||||
if test x$ac_cv_sys_symbol_underscore = xyes; then
|
||||
AC_DEFINE(WITH_SYMBOL_UNDERSCORE,1,
|
||||
[Defined if compiled symbols have a leading underscore])
|
||||
fi
|
||||
])
|
||||
|
||||
dnl Stolen from gcc
|
||||
dnl Define MKDIR_TAKES_ONE_ARG if mkdir accepts only one argument instead
|
||||
dnl of the usual 2.
|
||||
@ -748,18 +387,6 @@ if test $gnupg_cv_mkdir_takes_one_arg = yes ; then
|
||||
fi
|
||||
])
|
||||
|
||||
# GNUPG_AC_INIT([PACKAGE, VERSION, [ISDEVEL], BUG-REPORT)
|
||||
# ----------------------------------------
|
||||
# Call AC_INIT with an additional argument to indicate a development
|
||||
# version. If this is called ""svn", the global revision of the
|
||||
# repository will be appended, so that a version. The variable
|
||||
# SVN_REVISION will always be set. In case svn is not available 0
|
||||
# will be used for the revision.
|
||||
m4_define([GNUPG_AC_INIT],
|
||||
[
|
||||
m4_define(gnupg_ac_init_tmp, m4_esyscmd([echo -n $((svn info 2>/dev/null || \
|
||||
echo 'Revision: 0') |sed -n '/^Revision:/ {s/[^0-9]//gp;q}')]))
|
||||
SVN_REVISION="gnupg_ac_init_tmp[]"
|
||||
AC_INIT([$1], [$2][]m4_ifval([$3],[-[$3][]gnupg_ac_init_tmp],[]), [$4])
|
||||
])
|
||||
|
||||
|
||||
|
||||
|
1513
agent/ChangeLog
Normal file
90
agent/Makefile.am
Normal file
@ -0,0 +1,90 @@
|
||||
# Copyright (C) 2001, 2003, 2004, 2005 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is part of GnuPG.
|
||||
#
|
||||
# GnuPG is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# GnuPG is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
|
||||
# USA.
|
||||
|
||||
## Process this file with automake to produce Makefile.in
|
||||
|
||||
bin_PROGRAMS = gpg-agent
|
||||
libexec_PROGRAMS = gpg-protect-tool gpg-preset-passphrase
|
||||
noinst_PROGRAMS = $(TESTS)
|
||||
|
||||
AM_CPPFLAGS = -I$(top_srcdir)/gl -I$(top_srcdir)/common -I$(top_srcdir)/intl
|
||||
|
||||
include $(top_srcdir)/am/cmacros.am
|
||||
|
||||
AM_CFLAGS = $(LIBGCRYPT_CFLAGS) $(LIBASSUAN_CFLAGS) $(PTH_CFLAGS)
|
||||
|
||||
gpg_agent_SOURCES = \
|
||||
gpg-agent.c agent.h \
|
||||
command.c command-ssh.c \
|
||||
query.c \
|
||||
cache.c \
|
||||
trans.c \
|
||||
findkey.c \
|
||||
pksign.c \
|
||||
pkdecrypt.c \
|
||||
genkey.c \
|
||||
protect.c \
|
||||
trustlist.c \
|
||||
divert-scd.c \
|
||||
call-scd.c \
|
||||
learncard.c
|
||||
|
||||
|
||||
gpg_agent_LDADD = ../jnlib/libjnlib.a ../common/libcommon.a ../gl/libgnu.a \
|
||||
$(LIBGCRYPT_LIBS) $(PTH_LIBS) $(LIBASSUAN_LIBS) \
|
||||
-lgpg-error @LIBINTL@ $(NETLIBS)
|
||||
|
||||
gpg_protect_tool_SOURCES = \
|
||||
protect-tool.c \
|
||||
protect.c \
|
||||
minip12.c minip12.h
|
||||
|
||||
# Needs $(NETLIBS) for libsimple-pwquery.la.
|
||||
gpg_protect_tool_LDADD = ../common/libsimple-pwquery.a \
|
||||
../jnlib/libjnlib.a ../common/libcommon.a ../gl/libgnu.a \
|
||||
$(LIBGCRYPT_LIBS) -lgpg-error @LIBINTL@ $(NETLIBS)
|
||||
if HAVE_W32_SYSTEM
|
||||
gpg_protect_tool_LDADD += -lwsock32
|
||||
endif
|
||||
|
||||
gpg_preset_passphrase_SOURCES = \
|
||||
preset-passphrase.c
|
||||
|
||||
# Needs $(NETLIBS) for libsimple-pwquery.la.
|
||||
gpg_preset_passphrase_LDADD = ../common/libsimple-pwquery.a \
|
||||
../jnlib/libjnlib.a ../common/libcommon.a ../gl/libgnu.a \
|
||||
$(LIBGCRYPT_LIBS) -lgpg-error @LIBINTL@ $(NETLIBS)
|
||||
if HAVE_W32_SYSTEM
|
||||
gpg_preset_passphrase_LDADD += -lwsock32
|
||||
endif
|
||||
|
||||
#
|
||||
# Module tests
|
||||
#
|
||||
TESTS = t-protect
|
||||
|
||||
t_common_ldadd = ../jnlib/libjnlib.a ../common/libcommon.a ../gl/libgnu.a \
|
||||
$(LIBGCRYPT_LIBS) -lgpg-error @LIBINTL@
|
||||
|
||||
t_protect_SOURCES = t-protect.c protect.c
|
||||
t_protect_LDADD = $(t_common_ldadd)
|
||||
|
||||
|
||||
|
||||
|
319
agent/agent.h
Normal file
@ -0,0 +1,319 @@
|
||||
/* agent.h - Global definitions for the agent
|
||||
* Copyright (C) 2001, 2002, 2003, 2005 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of GnuPG.
|
||||
*
|
||||
* GnuPG is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* GnuPG is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
|
||||
* USA.
|
||||
*/
|
||||
|
||||
#ifndef AGENT_H
|
||||
#define AGENT_H
|
||||
|
||||
#ifdef GPG_ERR_SOURCE_DEFAULT
|
||||
#error GPG_ERR_SOURCE_DEFAULT already defined
|
||||
#endif
|
||||
#define GPG_ERR_SOURCE_DEFAULT GPG_ERR_SOURCE_GPGAGENT
|
||||
#include <gpg-error.h>
|
||||
#define map_assuan_err(a) \
|
||||
map_assuan_err_with_source (GPG_ERR_SOURCE_DEFAULT, (a))
|
||||
#include <errno.h>
|
||||
|
||||
#include <gcrypt.h>
|
||||
#include "../common/util.h"
|
||||
#include "../common/errors.h"
|
||||
#include "membuf.h"
|
||||
|
||||
/* Convenience function to be used instead of returning the old
|
||||
GNUPG_Out_Of_Core. */
|
||||
static inline gpg_error_t
|
||||
out_of_core (void)
|
||||
{
|
||||
return gpg_error (gpg_err_code_from_errno (errno));
|
||||
}
|
||||
|
||||
#define MAX_DIGEST_LEN 24
|
||||
|
||||
/* A large struct name "opt" to keep global flags */
|
||||
struct {
|
||||
unsigned int debug; /* Debug flags (DBG_foo_VALUE) */
|
||||
int verbose; /* Verbosity level */
|
||||
int quiet; /* Be as quiet as possible */
|
||||
int dry_run; /* Don't change any persistent data */
|
||||
int batch; /* Batch mode */
|
||||
const char *homedir; /* Configuration directory name */
|
||||
|
||||
/* Environment setting gathered at program start or changed using the
|
||||
Assuan command UPDATESTARTUPTTY. */
|
||||
char *startup_display;
|
||||
char *startup_ttyname;
|
||||
char *startup_ttytype;
|
||||
char *startup_lc_ctype;
|
||||
char *startup_lc_messages;
|
||||
|
||||
|
||||
const char *pinentry_program; /* Filename of the program to start as
|
||||
pinentry. */
|
||||
const char *scdaemon_program; /* Filename of the program to handle
|
||||
smartcard tasks. */
|
||||
int disable_scdaemon; /* Never use the SCdaemon. */
|
||||
int no_grab; /* Don't let the pinentry grab the keyboard */
|
||||
|
||||
/* The default and maximum TTL of cache entries. */
|
||||
unsigned long def_cache_ttl; /* Default. */
|
||||
unsigned long def_cache_ttl_ssh; /* for SSH. */
|
||||
unsigned long max_cache_ttl; /* Default. */
|
||||
unsigned long max_cache_ttl_ssh; /* for SSH. */
|
||||
|
||||
|
||||
int running_detached; /* We are running detached from the tty. */
|
||||
|
||||
int ignore_cache_for_signing;
|
||||
int allow_mark_trusted;
|
||||
int allow_preset_passphrase;
|
||||
int keep_tty; /* Don't switch the TTY (for pinentry) on request */
|
||||
int keep_display; /* Don't switch the DISPLAY (for pinentry) on request */
|
||||
int ssh_support; /* Enable ssh-agent emulation. */
|
||||
} opt;
|
||||
|
||||
|
||||
#define DBG_COMMAND_VALUE 1 /* debug commands i/o */
|
||||
#define DBG_MPI_VALUE 2 /* debug mpi details */
|
||||
#define DBG_CRYPTO_VALUE 4 /* debug low level crypto */
|
||||
#define DBG_MEMORY_VALUE 32 /* debug memory allocation stuff */
|
||||
#define DBG_CACHE_VALUE 64 /* debug the caching */
|
||||
#define DBG_MEMSTAT_VALUE 128 /* show memory statistics */
|
||||
#define DBG_HASHING_VALUE 512 /* debug hashing operations */
|
||||
#define DBG_ASSUAN_VALUE 1024
|
||||
|
||||
#define DBG_COMMAND (opt.debug & DBG_COMMAND_VALUE)
|
||||
#define DBG_CRYPTO (opt.debug & DBG_CRYPTO_VALUE)
|
||||
#define DBG_MEMORY (opt.debug & DBG_MEMORY_VALUE)
|
||||
#define DBG_CACHE (opt.debug & DBG_CACHE_VALUE)
|
||||
#define DBG_HASHING (opt.debug & DBG_HASHING_VALUE)
|
||||
#define DBG_ASSUAN (opt.debug & DBG_ASSUAN_VALUE)
|
||||
|
||||
struct server_local_s;
|
||||
struct scd_local_s;
|
||||
|
||||
/* Collection of data per session (aka connection). */
|
||||
struct server_control_s
|
||||
{
|
||||
/* Private data of the server (command.c). */
|
||||
struct server_local_s *server_local;
|
||||
|
||||
/* Private data of the SCdaemon (call-scd.c). */
|
||||
struct scd_local_s *scd_local;
|
||||
|
||||
int connection_fd; /* -1 or an identifier for the current connection. */
|
||||
|
||||
char *display;
|
||||
char *ttyname;
|
||||
char *ttytype;
|
||||
char *lc_ctype;
|
||||
char *lc_messages;
|
||||
struct {
|
||||
int algo;
|
||||
unsigned char value[MAX_DIGEST_LEN];
|
||||
int valuelen;
|
||||
int raw_value: 1;
|
||||
} digest;
|
||||
unsigned char keygrip[20];
|
||||
int have_keygrip;
|
||||
|
||||
int use_auth_call; /* Hack to send the PKAUTH command instead of the
|
||||
PKSIGN command to the scdaemon. */
|
||||
};
|
||||
typedef struct server_control_s *CTRL;
|
||||
typedef struct server_control_s *ctrl_t;
|
||||
|
||||
|
||||
struct pin_entry_info_s {
|
||||
int min_digits; /* min. number of digits required or 0 for freeform entry */
|
||||
int max_digits; /* max. number of allowed digits allowed*/
|
||||
int max_tries;
|
||||
int failed_tries;
|
||||
int (*check_cb)(struct pin_entry_info_s *); /* CB used to check the PIN */
|
||||
void *check_cb_arg; /* optional argument which might be of use in the CB */
|
||||
const char *cb_errtext; /* used by the cb to displaye a specific error */
|
||||
size_t max_length; /* allocated length of the buffer */
|
||||
char pin[1];
|
||||
};
|
||||
|
||||
|
||||
enum
|
||||
{
|
||||
PRIVATE_KEY_UNKNOWN = 0,
|
||||
PRIVATE_KEY_CLEAR = 1,
|
||||
PRIVATE_KEY_PROTECTED = 2,
|
||||
PRIVATE_KEY_SHADOWED = 3
|
||||
};
|
||||
|
||||
|
||||
/* Values for the cache_mode arguments. */
|
||||
typedef enum
|
||||
{
|
||||
CACHE_MODE_IGNORE = 0, /* Special mode to by pass the cache. */
|
||||
CACHE_MODE_ANY, /* Any mode except ignore matches. */
|
||||
CACHE_MODE_NORMAL, /* Normal cache (gpg-agent). */
|
||||
CACHE_MODE_USER, /* GET_PASSPHRASE related cache. */
|
||||
CACHE_MODE_SSH /* SSH related cache. */
|
||||
}
|
||||
cache_mode_t;
|
||||
|
||||
|
||||
/*-- gpg-agent.c --*/
|
||||
void agent_exit (int rc) JNLIB_GCC_A_NR; /* Also implemented in other tools */
|
||||
void agent_init_default_ctrl (struct server_control_s *ctrl);
|
||||
|
||||
/*-- command.c --*/
|
||||
void start_command_handler (int, int);
|
||||
|
||||
/*-- command-ssh.c --*/
|
||||
void start_command_handler_ssh (int);
|
||||
|
||||
/*-- findkey.c --*/
|
||||
int agent_write_private_key (const unsigned char *grip,
|
||||
const void *buffer, size_t length, int force);
|
||||
gpg_error_t agent_key_from_file (ctrl_t ctrl,
|
||||
const char *desc_text,
|
||||
const unsigned char *grip,
|
||||
unsigned char **shadow_info,
|
||||
cache_mode_t cache_mode,
|
||||
gcry_sexp_t *result);
|
||||
gpg_error_t agent_public_key_from_file (ctrl_t ctrl,
|
||||
const unsigned char *grip,
|
||||
gcry_sexp_t *result);
|
||||
int agent_key_available (const unsigned char *grip);
|
||||
|
||||
/*-- query.c --*/
|
||||
void initialize_module_query (void);
|
||||
void agent_query_dump_state (void);
|
||||
void agent_reset_query (ctrl_t ctrl);
|
||||
int agent_askpin (ctrl_t ctrl,
|
||||
const char *desc_text, const char *prompt_text,
|
||||
const char *inital_errtext,
|
||||
struct pin_entry_info_s *pininfo);
|
||||
int agent_get_passphrase (ctrl_t ctrl, char **retpass,
|
||||
const char *desc, const char *prompt,
|
||||
const char *errtext);
|
||||
int agent_get_confirmation (ctrl_t ctrl, const char *desc, const char *ok,
|
||||
const char *cancel);
|
||||
int agent_popup_message_start (ctrl_t ctrl, const char *desc,
|
||||
const char *ok_btn, const char *cancel_btn);
|
||||
void agent_popup_message_stop (ctrl_t ctrl);
|
||||
|
||||
|
||||
/*-- cache.c --*/
|
||||
void agent_flush_cache (void);
|
||||
int agent_put_cache (const char *key, cache_mode_t cache_mode,
|
||||
const char *data, int ttl);
|
||||
const char *agent_get_cache (const char *key, cache_mode_t cache_mode,
|
||||
void **cache_id);
|
||||
void agent_unlock_cache_entry (void **cache_id);
|
||||
|
||||
|
||||
/*-- pksign.c --*/
|
||||
int agent_pksign_do (ctrl_t ctrl, const char *desc_text,
|
||||
gcry_sexp_t *signature_sexp,
|
||||
cache_mode_t cache_mode);
|
||||
int agent_pksign (ctrl_t ctrl, const char *desc_text,
|
||||
membuf_t *outbuf, cache_mode_t cache_mode);
|
||||
|
||||
/*-- pkdecrypt.c --*/
|
||||
int agent_pkdecrypt (ctrl_t ctrl, const char *desc_text,
|
||||
const unsigned char *ciphertext, size_t ciphertextlen,
|
||||
membuf_t *outbuf);
|
||||
|
||||
/*-- genkey.c --*/
|
||||
int agent_genkey (ctrl_t ctrl,
|
||||
const char *keyparam, size_t keyparmlen, membuf_t *outbuf);
|
||||
int agent_protect_and_store (ctrl_t ctrl, gcry_sexp_t s_skey);
|
||||
|
||||
/*-- protect.c --*/
|
||||
int agent_protect (const unsigned char *plainkey, const char *passphrase,
|
||||
unsigned char **result, size_t *resultlen);
|
||||
int agent_unprotect (const unsigned char *protectedkey, const char *passphrase,
|
||||
unsigned char **result, size_t *resultlen);
|
||||
int agent_private_key_type (const unsigned char *privatekey);
|
||||
unsigned char *make_shadow_info (const char *serialno, const char *idstring);
|
||||
int agent_shadow_key (const unsigned char *pubkey,
|
||||
const unsigned char *shadow_info,
|
||||
unsigned char **result);
|
||||
int agent_get_shadow_info (const unsigned char *shadowkey,
|
||||
unsigned char const **shadow_info);
|
||||
|
||||
|
||||
/*-- trustlist.c --*/
|
||||
int agent_istrusted (const char *fpr);
|
||||
int agent_listtrusted (void *assuan_context);
|
||||
int agent_marktrusted (ctrl_t ctrl, const char *name,
|
||||
const char *fpr, int flag);
|
||||
void agent_trustlist_housekeeping (void);
|
||||
void agent_reload_trustlist (void);
|
||||
|
||||
|
||||
/*-- divert-scd.c --*/
|
||||
int divert_pksign (ctrl_t ctrl,
|
||||
const unsigned char *digest, size_t digestlen, int algo,
|
||||
const unsigned char *shadow_info, unsigned char **r_sig);
|
||||
int divert_pkdecrypt (ctrl_t ctrl,
|
||||
const unsigned char *cipher,
|
||||
const unsigned char *shadow_info,
|
||||
char **r_buf, size_t *r_len);
|
||||
int divert_generic_cmd (ctrl_t ctrl,
|
||||
const char *cmdline, void *assuan_context);
|
||||
|
||||
|
||||
/*-- call-scd.c --*/
|
||||
void initialize_module_call_scd (void);
|
||||
void agent_scd_dump_state (void);
|
||||
void agent_scd_check_aliveness (void);
|
||||
int agent_reset_scd (ctrl_t ctrl);
|
||||
int agent_card_learn (ctrl_t ctrl,
|
||||
void (*kpinfo_cb)(void*, const char *),
|
||||
void *kpinfo_cb_arg,
|
||||
void (*certinfo_cb)(void*, const char *),
|
||||
void *certinfo_cb_arg,
|
||||
void (*sinfo_cb)(void*, const char *,
|
||||
size_t, const char *),
|
||||
void *sinfo_cb_arg);
|
||||
int agent_card_serialno (ctrl_t ctrl, char **r_serialno);
|
||||
int agent_card_pksign (ctrl_t ctrl,
|
||||
const char *keyid,
|
||||
int (*getpin_cb)(void *, const char *, char*, size_t),
|
||||
void *getpin_cb_arg,
|
||||
const unsigned char *indata, size_t indatalen,
|
||||
unsigned char **r_buf, size_t *r_buflen);
|
||||
int agent_card_pkdecrypt (ctrl_t ctrl,
|
||||
const char *keyid,
|
||||
int (*getpin_cb)(void *, const char *, char*,size_t),
|
||||
void *getpin_cb_arg,
|
||||
const unsigned char *indata, size_t indatalen,
|
||||
char **r_buf, size_t *r_buflen);
|
||||
int agent_card_readcert (ctrl_t ctrl,
|
||||
const char *id, char **r_buf, size_t *r_buflen);
|
||||
int agent_card_readkey (ctrl_t ctrl, const char *id, unsigned char **r_buf);
|
||||
gpg_error_t agent_card_getattr (ctrl_t ctrl, const char *name, char **result);
|
||||
int agent_card_scd (ctrl_t ctrl, const char *cmdline,
|
||||
int (*getpin_cb)(void *, const char *, char*, size_t),
|
||||
void *getpin_cb_arg, void *assuan_context);
|
||||
|
||||
|
||||
/*-- learncard.c --*/
|
||||
int agent_handle_learn (ctrl_t ctrl, void *assuan_context);
|
||||
|
||||
|
||||
#endif /*AGENT_H*/
|
342
agent/cache.c
Normal file
@ -0,0 +1,342 @@
|
||||
/* cache.c - keep a cache of passphrases
|
||||
* Copyright (C) 2002 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of GnuPG.
|
||||
*
|
||||
* GnuPG is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* GnuPG is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
|
||||
* USA.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "agent.h"
|
||||
|
||||
struct secret_data_s {
|
||||
int totallen; /* this includes the padding */
|
||||
int datalen; /* actual data length */
|
||||
char data[1];
|
||||
};
|
||||
|
||||
typedef struct cache_item_s *ITEM;
|
||||
struct cache_item_s {
|
||||
ITEM next;
|
||||
time_t created;
|
||||
time_t accessed;
|
||||
int ttl; /* max. lifetime given in seconds, -1 one means infinite */
|
||||
int lockcount;
|
||||
struct secret_data_s *pw;
|
||||
cache_mode_t cache_mode;
|
||||
char key[1];
|
||||
};
|
||||
|
||||
|
||||
static ITEM thecache;
|
||||
|
||||
|
||||
static void
|
||||
release_data (struct secret_data_s *data)
|
||||
{
|
||||
xfree (data);
|
||||
}
|
||||
|
||||
static struct secret_data_s *
|
||||
new_data (const void *data, size_t length)
|
||||
{
|
||||
struct secret_data_s *d;
|
||||
int total;
|
||||
|
||||
/* we pad the data to 32 bytes so that it get more complicated
|
||||
finding something out by watching allocation patterns. This is
|
||||
usally not possible but we better assume nothing about our
|
||||
secure storage provider*/
|
||||
total = length + 32 - (length % 32);
|
||||
|
||||
d = gcry_malloc_secure (sizeof *d + total - 1);
|
||||
if (d)
|
||||
{
|
||||
d->totallen = total;
|
||||
d->datalen = length;
|
||||
memcpy (d->data, data, length);
|
||||
}
|
||||
return d;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* check whether there are items to expire */
|
||||
static void
|
||||
housekeeping (void)
|
||||
{
|
||||
ITEM r, rprev;
|
||||
time_t current = gnupg_get_time ();
|
||||
|
||||
/* First expire the actual data */
|
||||
for (r=thecache; r; r = r->next)
|
||||
{
|
||||
if (!r->lockcount && r->pw
|
||||
&& r->ttl >= 0 && r->accessed + r->ttl < current)
|
||||
{
|
||||
if (DBG_CACHE)
|
||||
log_debug (" expired `%s' (%ds after last access)\n",
|
||||
r->key, r->ttl);
|
||||
release_data (r->pw);
|
||||
r->pw = NULL;
|
||||
r->accessed = current;
|
||||
}
|
||||
}
|
||||
|
||||
/* Second, make sure that we also remove them based on the created stamp so
|
||||
that the user has to enter it from time to time. */
|
||||
for (r=thecache; r; r = r->next)
|
||||
{
|
||||
unsigned long maxttl;
|
||||
|
||||
switch (r->cache_mode)
|
||||
{
|
||||
case CACHE_MODE_SSH: maxttl = opt.max_cache_ttl_ssh; break;
|
||||
default: maxttl = opt.max_cache_ttl; break;
|
||||
}
|
||||
if (!r->lockcount && r->pw && r->created + maxttl < current)
|
||||
{
|
||||
if (DBG_CACHE)
|
||||
log_debug (" expired `%s' (%lus after creation)\n",
|
||||
r->key, opt.max_cache_ttl);
|
||||
release_data (r->pw);
|
||||
r->pw = NULL;
|
||||
r->accessed = current;
|
||||
}
|
||||
}
|
||||
|
||||
/* Third, make sure that we don't have too many items in the list.
|
||||
Expire old and unused entries after 30 minutes */
|
||||
for (rprev=NULL, r=thecache; r; )
|
||||
{
|
||||
if (!r->pw && r->ttl >= 0 && r->accessed + 60*30 < current)
|
||||
{
|
||||
if (r->lockcount)
|
||||
{
|
||||
log_error ("can't remove unused cache entry `%s' due to"
|
||||
" lockcount=%d\n",
|
||||
r->key, r->lockcount);
|
||||
r->accessed += 60*10; /* next error message in 10 minutes */
|
||||
rprev = r;
|
||||
r = r->next;
|
||||
}
|
||||
else
|
||||
{
|
||||
ITEM r2 = r->next;
|
||||
if (DBG_CACHE)
|
||||
log_debug (" removed `%s' (slot not used for 30m)\n", r->key);
|
||||
xfree (r);
|
||||
if (!rprev)
|
||||
thecache = r2;
|
||||
else
|
||||
rprev->next = r2;
|
||||
r = r2;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
rprev = r;
|
||||
r = r->next;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
agent_flush_cache (void)
|
||||
{
|
||||
ITEM r;
|
||||
|
||||
if (DBG_CACHE)
|
||||
log_debug ("agent_flush_cache\n");
|
||||
|
||||
for (r=thecache; r; r = r->next)
|
||||
{
|
||||
if (!r->lockcount && r->pw)
|
||||
{
|
||||
if (DBG_CACHE)
|
||||
log_debug (" flushing `%s'\n", r->key);
|
||||
release_data (r->pw);
|
||||
r->pw = NULL;
|
||||
r->accessed = 0;
|
||||
}
|
||||
else if (r->lockcount && r->pw)
|
||||
{
|
||||
if (DBG_CACHE)
|
||||
log_debug (" marked `%s' for flushing\n", r->key);
|
||||
r->accessed = 0;
|
||||
r->ttl = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Store DATA of length DATALEN in the cache under KEY and mark it
|
||||
with a maximum lifetime of TTL seconds. If there is already data
|
||||
under this key, it will be replaced. Using a DATA of NULL deletes
|
||||
the entry. A TTL of 0 is replaced by the default TTL and a TTL of
|
||||
-1 set infinite timeout. CACHE_MODE is stored with the cache entry
|
||||
and used t select different timeouts. */
|
||||
int
|
||||
agent_put_cache (const char *key, cache_mode_t cache_mode,
|
||||
const char *data, int ttl)
|
||||
{
|
||||
ITEM r;
|
||||
|
||||
if (DBG_CACHE)
|
||||
log_debug ("agent_put_cache `%s' requested ttl=%d mode=%d\n",
|
||||
key, ttl, cache_mode);
|
||||
housekeeping ();
|
||||
|
||||
if (!ttl)
|
||||
{
|
||||
switch(cache_mode)
|
||||
{
|
||||
case CACHE_MODE_SSH: ttl = opt.def_cache_ttl_ssh; break;
|
||||
default: ttl = opt.def_cache_ttl; break;
|
||||
}
|
||||
}
|
||||
if (!ttl || cache_mode == CACHE_MODE_IGNORE)
|
||||
return 0;
|
||||
|
||||
for (r=thecache; r; r = r->next)
|
||||
{
|
||||
if (!r->lockcount && !strcmp (r->key, key))
|
||||
break;
|
||||
}
|
||||
if (r)
|
||||
{ /* replace */
|
||||
if (r->pw)
|
||||
{
|
||||
release_data (r->pw);
|
||||
r->pw = NULL;
|
||||
}
|
||||
if (data)
|
||||
{
|
||||
r->created = r->accessed = gnupg_get_time ();
|
||||
r->ttl = ttl;
|
||||
r->cache_mode = cache_mode;
|
||||
r->pw = new_data (data, strlen (data)+1);
|
||||
if (!r->pw)
|
||||
log_error ("out of core while allocating new cache item\n");
|
||||
}
|
||||
}
|
||||
else if (data)
|
||||
{ /* simply insert */
|
||||
r = xtrycalloc (1, sizeof *r + strlen (key));
|
||||
if (!r)
|
||||
log_error ("out of core while allocating new cache control\n");
|
||||
else
|
||||
{
|
||||
strcpy (r->key, key);
|
||||
r->created = r->accessed = gnupg_get_time ();
|
||||
r->ttl = ttl;
|
||||
r->cache_mode = cache_mode;
|
||||
r->pw = new_data (data, strlen (data)+1);
|
||||
if (!r->pw)
|
||||
{
|
||||
log_error ("out of core while allocating new cache item\n");
|
||||
xfree (r);
|
||||
}
|
||||
else
|
||||
{
|
||||
r->next = thecache;
|
||||
thecache = r;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* Try to find an item in the cache. Note that we currently don't
|
||||
make use of CACHE_MODE. */
|
||||
const char *
|
||||
agent_get_cache (const char *key, cache_mode_t cache_mode, void **cache_id)
|
||||
{
|
||||
ITEM r;
|
||||
|
||||
if (cache_mode == CACHE_MODE_IGNORE)
|
||||
return NULL;
|
||||
|
||||
if (DBG_CACHE)
|
||||
log_debug ("agent_get_cache `%s'...\n", key);
|
||||
housekeeping ();
|
||||
|
||||
/* first try to find one with no locks - this is an updated cache
|
||||
entry: We might have entries with a lockcount and without a
|
||||
lockcount. */
|
||||
for (r=thecache; r; r = r->next)
|
||||
{
|
||||
if (!r->lockcount && r->pw && !strcmp (r->key, key))
|
||||
{
|
||||
/* put_cache does only put strings into the cache, so we
|
||||
don't need the lengths */
|
||||
r->accessed = gnupg_get_time ();
|
||||
if (DBG_CACHE)
|
||||
log_debug ("... hit\n");
|
||||
r->lockcount++;
|
||||
*cache_id = r;
|
||||
return r->pw->data;
|
||||
}
|
||||
}
|
||||
/* again, but this time get even one with a lockcount set */
|
||||
for (r=thecache; r; r = r->next)
|
||||
{
|
||||
if (r->pw && !strcmp (r->key, key))
|
||||
{
|
||||
r->accessed = gnupg_get_time ();
|
||||
if (DBG_CACHE)
|
||||
log_debug ("... hit (locked)\n");
|
||||
r->lockcount++;
|
||||
*cache_id = r;
|
||||
return r->pw->data;
|
||||
}
|
||||
}
|
||||
if (DBG_CACHE)
|
||||
log_debug ("... miss\n");
|
||||
|
||||
*cache_id = NULL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
agent_unlock_cache_entry (void **cache_id)
|
||||
{
|
||||
ITEM r;
|
||||
|
||||
for (r=thecache; r; r = r->next)
|
||||
{
|
||||
if (r == *cache_id)
|
||||
{
|
||||
if (!r->lockcount)
|
||||
log_error ("trying to unlock non-locked cache entry `%s'\n",
|
||||
r->key);
|
||||
else
|
||||
r->lockcount--;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
1092
agent/call-scd.c
Normal file
2880
agent/command-ssh.c
Normal file
1112
agent/command.c
Normal file
418
agent/divert-scd.c
Normal file
@ -0,0 +1,418 @@
|
||||
/* divert-scd.c - divert operations to the scdaemon
|
||||
* Copyright (C) 2002, 2003 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of GnuPG.
|
||||
*
|
||||
* GnuPG is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* GnuPG is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
|
||||
* USA.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <assert.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include "agent.h"
|
||||
#include "sexp-parse.h"
|
||||
#include "i18n.h"
|
||||
|
||||
|
||||
static int
|
||||
ask_for_card (CTRL ctrl, const unsigned char *shadow_info, char **r_kid)
|
||||
{
|
||||
int rc, i;
|
||||
const unsigned char *s;
|
||||
size_t n;
|
||||
char *serialno;
|
||||
int no_card = 0;
|
||||
char *desc;
|
||||
char *want_sn, *want_kid;
|
||||
int want_sn_displen;
|
||||
|
||||
*r_kid = NULL;
|
||||
s = shadow_info;
|
||||
if (*s != '(')
|
||||
return gpg_error (GPG_ERR_INV_SEXP);
|
||||
s++;
|
||||
n = snext (&s);
|
||||
if (!n)
|
||||
return gpg_error (GPG_ERR_INV_SEXP);
|
||||
want_sn = xtrymalloc (n*2+1);
|
||||
if (!want_sn)
|
||||
return out_of_core ();
|
||||
for (i=0; i < n; i++)
|
||||
sprintf (want_sn+2*i, "%02X", s[i]);
|
||||
s += n;
|
||||
/* We assume that a 20 byte serial number is a standard one which
|
||||
seems to have the property to have a zero in the last nibble. We
|
||||
don't display this '0' because it may confuse the user */
|
||||
want_sn_displen = strlen (want_sn);
|
||||
if (want_sn_displen == 20 && want_sn[19] == '0')
|
||||
want_sn_displen--;
|
||||
|
||||
n = snext (&s);
|
||||
if (!n)
|
||||
return gpg_error (GPG_ERR_INV_SEXP);
|
||||
want_kid = xtrymalloc (n+1);
|
||||
if (!want_kid)
|
||||
{
|
||||
gpg_error_t tmperr = out_of_core ();
|
||||
xfree (want_sn);
|
||||
return tmperr;
|
||||
}
|
||||
memcpy (want_kid, s, n);
|
||||
want_kid[n] = 0;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
rc = agent_card_serialno (ctrl, &serialno);
|
||||
if (!rc)
|
||||
{
|
||||
log_debug ("detected card with S/N %s\n", serialno);
|
||||
i = strcmp (serialno, want_sn);
|
||||
xfree (serialno);
|
||||
serialno = NULL;
|
||||
if (!i)
|
||||
{
|
||||
xfree (want_sn);
|
||||
*r_kid = want_kid;
|
||||
return 0; /* yes, we have the correct card */
|
||||
}
|
||||
}
|
||||
else if (gpg_err_code (rc) == GPG_ERR_CARD_NOT_PRESENT)
|
||||
{
|
||||
log_debug ("no card present\n");
|
||||
rc = 0;
|
||||
no_card = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
log_error ("error accesing card: %s\n", gpg_strerror (rc));
|
||||
}
|
||||
|
||||
if (!rc)
|
||||
{
|
||||
if (asprintf (&desc,
|
||||
"%s:%%0A%%0A"
|
||||
" \"%.*s\"",
|
||||
no_card? "Please insert the card with serial number"
|
||||
: "Please remove the current card and "
|
||||
"insert the one with serial number",
|
||||
want_sn_displen, want_sn) < 0)
|
||||
{
|
||||
rc = out_of_core ();
|
||||
}
|
||||
else
|
||||
{
|
||||
rc = agent_get_confirmation (ctrl, desc, NULL, NULL);
|
||||
free (desc);
|
||||
}
|
||||
}
|
||||
if (rc)
|
||||
{
|
||||
xfree (want_sn);
|
||||
xfree (want_kid);
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Put the DIGEST into an DER encoded container and return it in R_VAL. */
|
||||
static int
|
||||
encode_md_for_card (const unsigned char *digest, size_t digestlen, int algo,
|
||||
unsigned char **r_val, size_t *r_len)
|
||||
{
|
||||
unsigned char *frame;
|
||||
unsigned char asn[100];
|
||||
size_t asnlen;
|
||||
|
||||
*r_val = NULL;
|
||||
*r_len = 0;
|
||||
|
||||
asnlen = DIM(asn);
|
||||
if (gcry_md_algo_info (algo, GCRYCTL_GET_ASNOID, asn, &asnlen))
|
||||
{
|
||||
log_error ("no object identifier for algo %d\n", algo);
|
||||
return gpg_error (GPG_ERR_INTERNAL);
|
||||
}
|
||||
|
||||
frame = xtrymalloc (asnlen + digestlen);
|
||||
if (!frame)
|
||||
return out_of_core ();
|
||||
memcpy (frame, asn, asnlen);
|
||||
memcpy (frame+asnlen, digest, digestlen);
|
||||
if (DBG_CRYPTO)
|
||||
log_printhex ("encoded hash:", frame, asnlen+digestlen);
|
||||
|
||||
*r_val = frame;
|
||||
*r_len = asnlen+digestlen;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* Callback used to ask for the PIN which should be set into BUF. The
|
||||
buf has been allocated by the caller and is of size MAXBUF which
|
||||
includes the terminating null. The function should return an UTF-8
|
||||
string with the passphrase, the buffer may optionally be padded
|
||||
with arbitrary characters.
|
||||
|
||||
INFO gets displayed as part of a generic string. However if the
|
||||
first character of INFO is a vertical bar all up to the next
|
||||
verical bar are considered flags and only everything after the
|
||||
second vertical bar gets displayed as the full prompt.
|
||||
|
||||
Flags:
|
||||
|
||||
'N' = New PIN, this requests a second prompt to repeat the the
|
||||
PIN. If the PIN is not correctly repeated it starts from
|
||||
all over.
|
||||
'A' = The PIN is an Admin PIN, SO-PIN, PUK or alike.
|
||||
|
||||
Example:
|
||||
|
||||
"|AN|Please enter the new security officer's PIN"
|
||||
|
||||
The text "Please ..." will get displayed and the flags 'A' and 'N'
|
||||
are considered.
|
||||
*/
|
||||
static int
|
||||
getpin_cb (void *opaque, const char *info, char *buf, size_t maxbuf)
|
||||
{
|
||||
struct pin_entry_info_s *pi;
|
||||
int rc;
|
||||
ctrl_t ctrl = opaque;
|
||||
const char *ends, *s;
|
||||
int any_flags = 0;
|
||||
int newpin = 0;
|
||||
const char *again_text = NULL;
|
||||
const char *prompt = "PIN";
|
||||
|
||||
if (buf && maxbuf < 2)
|
||||
return gpg_error (GPG_ERR_INV_VALUE);
|
||||
|
||||
/* Parse the flags. */
|
||||
if (info && *info =='|' && (ends=strchr (info+1, '|')))
|
||||
{
|
||||
for (s=info+1; s < ends; s++)
|
||||
{
|
||||
if (*s == 'A')
|
||||
prompt = _("Admin PIN");
|
||||
else if (*s == 'N')
|
||||
newpin = 1;
|
||||
}
|
||||
info = ends+1;
|
||||
any_flags = 1;
|
||||
}
|
||||
else if (info && *info == '|')
|
||||
log_debug ("pin_cb called without proper PIN info hack\n");
|
||||
|
||||
/* If BUF has been passed as NULL, we are in keypad mode: The
|
||||
callback opens the popup and immediatley returns. */
|
||||
if (!buf)
|
||||
{
|
||||
if (maxbuf == 0) /* Close the pinentry. */
|
||||
{
|
||||
agent_popup_message_stop (ctrl);
|
||||
rc = 0;
|
||||
}
|
||||
else if (maxbuf == 1) /* Open the pinentry. */
|
||||
{
|
||||
rc = agent_popup_message_start (ctrl, info, NULL, NULL);
|
||||
}
|
||||
else
|
||||
rc = gpg_error (GPG_ERR_INV_VALUE);
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* FIXME: keep PI and TRIES in OPAQUE. Frankly this is a whole
|
||||
mess because we should call the card's verify function from the
|
||||
pinentry check pin CB. */
|
||||
again:
|
||||
pi = gcry_calloc_secure (1, sizeof (*pi) + maxbuf + 10);
|
||||
if (!pi)
|
||||
return gpg_error_from_errno (errno);
|
||||
pi->max_length = maxbuf-1;
|
||||
pi->min_digits = 0; /* we want a real passphrase */
|
||||
pi->max_digits = 8;
|
||||
pi->max_tries = 3;
|
||||
|
||||
if (any_flags)
|
||||
{
|
||||
rc = agent_askpin (ctrl, info, prompt, again_text, pi);
|
||||
again_text = NULL;
|
||||
if (!rc && newpin)
|
||||
{
|
||||
struct pin_entry_info_s *pi2;
|
||||
pi2 = gcry_calloc_secure (1, sizeof (*pi) + maxbuf + 10);
|
||||
if (!pi2)
|
||||
{
|
||||
rc = gpg_error_from_errno (errno);
|
||||
xfree (pi);
|
||||
return rc;
|
||||
}
|
||||
pi2->max_length = maxbuf-1;
|
||||
pi2->min_digits = 0;
|
||||
pi2->max_digits = 8;
|
||||
pi2->max_tries = 1;
|
||||
rc = agent_askpin (ctrl, _("Repeat this PIN"), prompt, NULL, pi2);
|
||||
if (!rc && strcmp (pi->pin, pi2->pin))
|
||||
{
|
||||
again_text = N_("PIN not correctly repeated; try again");
|
||||
xfree (pi2);
|
||||
xfree (pi);
|
||||
goto again;
|
||||
}
|
||||
xfree (pi2);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
char *desc;
|
||||
if ( asprintf (&desc,
|
||||
_("Please enter the PIN%s%s%s to unlock the card"),
|
||||
info? " (`":"",
|
||||
info? info:"",
|
||||
info? "')":"") < 0)
|
||||
desc = NULL;
|
||||
rc = agent_askpin (ctrl, desc?desc:info, prompt, NULL, pi);
|
||||
free (desc);
|
||||
}
|
||||
|
||||
if (!rc)
|
||||
{
|
||||
strncpy (buf, pi->pin, maxbuf-1);
|
||||
buf[maxbuf-1] = 0;
|
||||
}
|
||||
xfree (pi);
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
int
|
||||
divert_pksign (CTRL ctrl,
|
||||
const unsigned char *digest, size_t digestlen, int algo,
|
||||
const unsigned char *shadow_info, unsigned char **r_sig)
|
||||
{
|
||||
int rc;
|
||||
char *kid;
|
||||
size_t siglen;
|
||||
unsigned char *sigval;
|
||||
unsigned char *data;
|
||||
size_t ndata;
|
||||
|
||||
rc = ask_for_card (ctrl, shadow_info, &kid);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
rc = encode_md_for_card (digest, digestlen, algo,
|
||||
&data, &ndata);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
rc = agent_card_pksign (ctrl, kid, getpin_cb, ctrl,
|
||||
data, ndata, &sigval, &siglen);
|
||||
if (!rc)
|
||||
*r_sig = sigval;
|
||||
xfree (data);
|
||||
xfree (kid);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
/* Decrypt the the value given asn an S-expression in CIPHER using the
|
||||
key identified by SHADOW_INFO and return the plaintext in an
|
||||
allocated buffer in R_BUF. */
|
||||
int
|
||||
divert_pkdecrypt (CTRL ctrl,
|
||||
const unsigned char *cipher,
|
||||
const unsigned char *shadow_info,
|
||||
char **r_buf, size_t *r_len)
|
||||
{
|
||||
int rc;
|
||||
char *kid;
|
||||
const unsigned char *s;
|
||||
size_t n;
|
||||
const unsigned char *ciphertext;
|
||||
size_t ciphertextlen;
|
||||
char *plaintext;
|
||||
size_t plaintextlen;
|
||||
|
||||
s = cipher;
|
||||
if (*s != '(')
|
||||
return gpg_error (GPG_ERR_INV_SEXP);
|
||||
s++;
|
||||
n = snext (&s);
|
||||
if (!n)
|
||||
return gpg_error (GPG_ERR_INV_SEXP);
|
||||
if (!smatch (&s, n, "enc-val"))
|
||||
return gpg_error (GPG_ERR_UNKNOWN_SEXP);
|
||||
if (*s != '(')
|
||||
return gpg_error (GPG_ERR_UNKNOWN_SEXP);
|
||||
s++;
|
||||
n = snext (&s);
|
||||
if (!n)
|
||||
return gpg_error (GPG_ERR_INV_SEXP);
|
||||
if (!smatch (&s, n, "rsa"))
|
||||
return gpg_error (GPG_ERR_UNSUPPORTED_ALGORITHM);
|
||||
if (*s != '(')
|
||||
return gpg_error (GPG_ERR_UNKNOWN_SEXP);
|
||||
s++;
|
||||
n = snext (&s);
|
||||
if (!n)
|
||||
return gpg_error (GPG_ERR_INV_SEXP);
|
||||
if (!smatch (&s, n, "a"))
|
||||
return gpg_error (GPG_ERR_UNKNOWN_SEXP);
|
||||
n = snext (&s);
|
||||
if (!n)
|
||||
return gpg_error (GPG_ERR_UNKNOWN_SEXP);
|
||||
ciphertext = s;
|
||||
ciphertextlen = n;
|
||||
|
||||
rc = ask_for_card (ctrl, shadow_info, &kid);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
rc = agent_card_pkdecrypt (ctrl, kid, getpin_cb, ctrl,
|
||||
ciphertext, ciphertextlen,
|
||||
&plaintext, &plaintextlen);
|
||||
if (!rc)
|
||||
{
|
||||
*r_buf = plaintext;
|
||||
*r_len = plaintextlen;
|
||||
}
|
||||
xfree (kid);
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
divert_generic_cmd (CTRL ctrl, const char *cmdline, void *assuan_context)
|
||||
{
|
||||
return agent_card_scd (ctrl, cmdline, getpin_cb, ctrl, assuan_context);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
732
agent/findkey.c
Normal file
@ -0,0 +1,732 @@
|
||||
/* findkey.c - locate the secret key
|
||||
* Copyright (C) 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of GnuPG.
|
||||
*
|
||||
* GnuPG is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* GnuPG is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
|
||||
* USA.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <fcntl.h>
|
||||
#include <assert.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/stat.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "agent.h"
|
||||
|
||||
/* Helper to pass data to the check callback of the unprotect function. */
|
||||
struct try_unprotect_arg_s {
|
||||
const unsigned char *protected_key;
|
||||
unsigned char *unprotected_key;
|
||||
};
|
||||
|
||||
|
||||
/* Write an S-expression formatted key to our key storage. With FORCE
|
||||
pased as true an existsing key with the given GRIP will get
|
||||
overwritten. */
|
||||
int
|
||||
agent_write_private_key (const unsigned char *grip,
|
||||
const void *buffer, size_t length, int force)
|
||||
{
|
||||
int i;
|
||||
char *fname;
|
||||
FILE *fp;
|
||||
char hexgrip[40+4+1];
|
||||
int fd;
|
||||
|
||||
for (i=0; i < 20; i++)
|
||||
sprintf (hexgrip+2*i, "%02X", grip[i]);
|
||||
strcpy (hexgrip+40, ".key");
|
||||
|
||||
fname = make_filename (opt.homedir, GNUPG_PRIVATE_KEYS_DIR, hexgrip, NULL);
|
||||
|
||||
if (!force && !access (fname, F_OK))
|
||||
{
|
||||
log_error ("secret key file `%s' already exists\n", fname);
|
||||
xfree (fname);
|
||||
return gpg_error (GPG_ERR_GENERAL);
|
||||
}
|
||||
|
||||
/* In FORCE mode we would like to create FNAME but only if it does
|
||||
not already exist. We cannot make this guarantee just using
|
||||
POSIX (GNU provides the "x" opentype for fopen, however, this is
|
||||
not portable). Thus, we use the more flexible open function and
|
||||
then use fdopen to obtain a stream. */
|
||||
fd = open (fname, force? (O_CREAT | O_TRUNC | O_WRONLY)
|
||||
: (O_CREAT | O_EXCL | O_WRONLY),
|
||||
S_IRUSR | S_IWUSR
|
||||
#ifndef HAVE_W32_SYSTEM
|
||||
| S_IRGRP
|
||||
#endif
|
||||
);
|
||||
if (fd < 0)
|
||||
fp = NULL;
|
||||
else
|
||||
{
|
||||
fp = fdopen (fd, "wb");
|
||||
if (!fp)
|
||||
{
|
||||
int save_e = errno;
|
||||
close (fd);
|
||||
errno = save_e;
|
||||
}
|
||||
}
|
||||
|
||||
if (!fp)
|
||||
{
|
||||
gpg_error_t tmperr = gpg_error (gpg_err_code_from_errno (errno));
|
||||
log_error ("can't create `%s': %s\n", fname, strerror (errno));
|
||||
xfree (fname);
|
||||
return tmperr;
|
||||
}
|
||||
|
||||
if (fwrite (buffer, length, 1, fp) != 1)
|
||||
{
|
||||
gpg_error_t tmperr = gpg_error (gpg_err_code_from_errno (errno));
|
||||
log_error ("error writing `%s': %s\n", fname, strerror (errno));
|
||||
fclose (fp);
|
||||
remove (fname);
|
||||
xfree (fname);
|
||||
return tmperr;
|
||||
}
|
||||
if ( fclose (fp) )
|
||||
{
|
||||
gpg_error_t tmperr = gpg_error (gpg_err_code_from_errno (errno));
|
||||
log_error ("error closing `%s': %s\n", fname, strerror (errno));
|
||||
remove (fname);
|
||||
xfree (fname);
|
||||
return tmperr;
|
||||
}
|
||||
|
||||
xfree (fname);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* Callback function to try the unprotection from the passpharse query
|
||||
code. */
|
||||
static int
|
||||
try_unprotect_cb (struct pin_entry_info_s *pi)
|
||||
{
|
||||
struct try_unprotect_arg_s *arg = pi->check_cb_arg;
|
||||
size_t dummy;
|
||||
|
||||
assert (!arg->unprotected_key);
|
||||
return agent_unprotect (arg->protected_key, pi->pin,
|
||||
&arg->unprotected_key, &dummy);
|
||||
}
|
||||
|
||||
|
||||
/* Modify a Key description, replacing certain special format
|
||||
characters. List of currently supported replacements:
|
||||
|
||||
%% - Replaced by a single %
|
||||
%c - Replaced by the content of COMMENT.
|
||||
|
||||
The functions returns 0 on success or an error code. On success a
|
||||
newly allocated string is stored at the address of RESULT.
|
||||
*/
|
||||
static gpg_error_t
|
||||
modify_description (const char *in, const char *comment, char **result)
|
||||
{
|
||||
size_t comment_length;
|
||||
size_t in_len;
|
||||
size_t out_len;
|
||||
char *out;
|
||||
size_t i;
|
||||
int special, pass;
|
||||
|
||||
comment_length = strlen (comment);
|
||||
in_len = strlen (in);
|
||||
|
||||
/* First pass calculates the length, second pass does the actual
|
||||
copying. */
|
||||
out = NULL;
|
||||
out_len = 0;
|
||||
for (pass=0; pass < 2; pass++)
|
||||
{
|
||||
special = 0;
|
||||
for (i = 0; i < in_len; i++)
|
||||
{
|
||||
if (special)
|
||||
{
|
||||
special = 0;
|
||||
switch (in[i])
|
||||
{
|
||||
case '%':
|
||||
if (out)
|
||||
*out++ = '%';
|
||||
else
|
||||
out_len++;
|
||||
break;
|
||||
|
||||
case 'c': /* Comment. */
|
||||
if (out)
|
||||
{
|
||||
memcpy (out, comment, comment_length);
|
||||
out += comment_length;
|
||||
}
|
||||
else
|
||||
out_len += comment_length;
|
||||
break;
|
||||
|
||||
default: /* Invalid special sequences are kept as they are. */
|
||||
if (out)
|
||||
{
|
||||
*out++ = '%';
|
||||
*out++ = in[i];
|
||||
}
|
||||
else
|
||||
out_len+=2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (in[i] == '%')
|
||||
special = 1;
|
||||
else
|
||||
{
|
||||
if (out)
|
||||
*out++ = in[i];
|
||||
else
|
||||
out_len++;
|
||||
}
|
||||
}
|
||||
|
||||
if (!pass)
|
||||
{
|
||||
*result = out = xtrymalloc (out_len + 1);
|
||||
if (!out)
|
||||
return gpg_error_from_errno (errno);
|
||||
}
|
||||
}
|
||||
|
||||
*out = 0;
|
||||
assert (*result + out_len == out);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Unprotect the canconical encoded S-expression key in KEYBUF. GRIP
|
||||
should be the hex encoded keygrip of that key to be used with the
|
||||
caching mechanism. DESC_TEXT may be set to override the default
|
||||
description used for the pinentry. */
|
||||
static int
|
||||
unprotect (ctrl_t ctrl, const char *desc_text,
|
||||
unsigned char **keybuf, const unsigned char *grip,
|
||||
cache_mode_t cache_mode)
|
||||
{
|
||||
struct pin_entry_info_s *pi;
|
||||
struct try_unprotect_arg_s arg;
|
||||
int rc, i;
|
||||
unsigned char *result;
|
||||
size_t resultlen;
|
||||
char hexgrip[40+1];
|
||||
|
||||
for (i=0; i < 20; i++)
|
||||
sprintf (hexgrip+2*i, "%02X", grip[i]);
|
||||
hexgrip[40] = 0;
|
||||
|
||||
/* First try to get it from the cache - if there is none or we can't
|
||||
unprotect it, we fall back to ask the user */
|
||||
if (cache_mode != CACHE_MODE_IGNORE)
|
||||
{
|
||||
void *cache_marker;
|
||||
const char *pw;
|
||||
|
||||
pw = agent_get_cache (hexgrip, cache_mode, &cache_marker);
|
||||
if (pw)
|
||||
{
|
||||
rc = agent_unprotect (*keybuf, pw, &result, &resultlen);
|
||||
agent_unlock_cache_entry (&cache_marker);
|
||||
if (!rc)
|
||||
{
|
||||
xfree (*keybuf);
|
||||
*keybuf = result;
|
||||
return 0;
|
||||
}
|
||||
rc = 0;
|
||||
}
|
||||
}
|
||||
|
||||
pi = gcry_calloc_secure (1, sizeof (*pi) + 100);
|
||||
if (!pi)
|
||||
return gpg_error_from_errno (errno);
|
||||
pi->max_length = 100;
|
||||
pi->min_digits = 0; /* we want a real passphrase */
|
||||
pi->max_digits = 8;
|
||||
pi->max_tries = 3;
|
||||
pi->check_cb = try_unprotect_cb;
|
||||
arg.protected_key = *keybuf;
|
||||
arg.unprotected_key = NULL;
|
||||
pi->check_cb_arg = &arg;
|
||||
|
||||
rc = agent_askpin (ctrl, desc_text, NULL, NULL, pi);
|
||||
if (!rc)
|
||||
{
|
||||
assert (arg.unprotected_key);
|
||||
agent_put_cache (hexgrip, cache_mode, pi->pin, 0);
|
||||
xfree (*keybuf);
|
||||
*keybuf = arg.unprotected_key;
|
||||
}
|
||||
xfree (pi);
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
/* Read the key identified by GRIP from the private key directory and
|
||||
return it as an gcrypt S-expression object in RESULT. On failure
|
||||
returns an error code and stores NULL at RESULT. */
|
||||
static gpg_error_t
|
||||
read_key_file (const unsigned char *grip, gcry_sexp_t *result)
|
||||
{
|
||||
int i, rc;
|
||||
char *fname;
|
||||
FILE *fp;
|
||||
struct stat st;
|
||||
unsigned char *buf;
|
||||
size_t buflen, erroff;
|
||||
gcry_sexp_t s_skey;
|
||||
char hexgrip[40+4+1];
|
||||
|
||||
*result = NULL;
|
||||
|
||||
for (i=0; i < 20; i++)
|
||||
sprintf (hexgrip+2*i, "%02X", grip[i]);
|
||||
strcpy (hexgrip+40, ".key");
|
||||
|
||||
fname = make_filename (opt.homedir, GNUPG_PRIVATE_KEYS_DIR, hexgrip, NULL);
|
||||
fp = fopen (fname, "rb");
|
||||
if (!fp)
|
||||
{
|
||||
rc = gpg_error_from_errno (errno);
|
||||
log_error ("can't open `%s': %s\n", fname, strerror (errno));
|
||||
xfree (fname);
|
||||
return rc;
|
||||
}
|
||||
|
||||
if (fstat (fileno(fp), &st))
|
||||
{
|
||||
rc = gpg_error_from_errno (errno);
|
||||
log_error ("can't stat `%s': %s\n", fname, strerror (errno));
|
||||
xfree (fname);
|
||||
fclose (fp);
|
||||
return rc;
|
||||
}
|
||||
|
||||
buflen = st.st_size;
|
||||
buf = xtrymalloc (buflen+1);
|
||||
if (!buf || fread (buf, buflen, 1, fp) != 1)
|
||||
{
|
||||
rc = gpg_error_from_errno (errno);
|
||||
log_error ("error reading `%s': %s\n", fname, strerror (errno));
|
||||
xfree (fname);
|
||||
fclose (fp);
|
||||
xfree (buf);
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* Convert the file into a gcrypt S-expression object. */
|
||||
rc = gcry_sexp_sscan (&s_skey, &erroff, (char*)buf, buflen);
|
||||
xfree (fname);
|
||||
fclose (fp);
|
||||
xfree (buf);
|
||||
if (rc)
|
||||
{
|
||||
log_error ("failed to build S-Exp (off=%u): %s\n",
|
||||
(unsigned int)erroff, gpg_strerror (rc));
|
||||
return rc;
|
||||
}
|
||||
*result = s_skey;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* Return the secret key as an S-Exp in RESULT after locating it using
|
||||
the grip. Returns NULL in RESULT if the operation should be
|
||||
diverted to a token; SHADOW_INFO will point then to an allocated
|
||||
S-Expression with the shadow_info part from the file. CACHE_MODE
|
||||
defines now the cache shall be used. DESC_TEXT may be set to
|
||||
present a custom description for the pinentry. */
|
||||
gpg_error_t
|
||||
agent_key_from_file (ctrl_t ctrl, const char *desc_text,
|
||||
const unsigned char *grip, unsigned char **shadow_info,
|
||||
cache_mode_t cache_mode, gcry_sexp_t *result)
|
||||
{
|
||||
int rc;
|
||||
unsigned char *buf;
|
||||
size_t len, buflen, erroff;
|
||||
gcry_sexp_t s_skey;
|
||||
int got_shadow_info = 0;
|
||||
|
||||
*result = NULL;
|
||||
if (shadow_info)
|
||||
*shadow_info = NULL;
|
||||
|
||||
rc = read_key_file (grip, &s_skey);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
/* For use with the protection functions we also need the key as an
|
||||
canonical encoded S-expression in abuffer. Create this buffer
|
||||
now. */
|
||||
len = gcry_sexp_sprint (s_skey, GCRYSEXP_FMT_CANON, NULL, 0);
|
||||
assert (len);
|
||||
buf = xtrymalloc (len);
|
||||
if (!buf)
|
||||
{
|
||||
rc = gpg_error_from_errno (errno);
|
||||
gcry_sexp_release (s_skey);
|
||||
return rc;
|
||||
}
|
||||
len = gcry_sexp_sprint (s_skey, GCRYSEXP_FMT_CANON, buf, len);
|
||||
assert (len);
|
||||
|
||||
|
||||
switch (agent_private_key_type (buf))
|
||||
{
|
||||
case PRIVATE_KEY_CLEAR:
|
||||
break; /* no unprotection needed */
|
||||
case PRIVATE_KEY_PROTECTED:
|
||||
{
|
||||
gcry_sexp_t comment_sexp;
|
||||
size_t comment_length;
|
||||
char *desc_text_final;
|
||||
const char *comment = NULL;
|
||||
|
||||
/* Note, that we will take the comment as a C string for
|
||||
display purposes; i.e. all stuff beyond a Nul character is
|
||||
ignored. */
|
||||
comment_sexp = gcry_sexp_find_token (s_skey, "comment", 0);
|
||||
if (comment_sexp)
|
||||
comment = gcry_sexp_nth_data (comment_sexp, 1, &comment_length);
|
||||
if (!comment)
|
||||
{
|
||||
comment = "";
|
||||
comment_length = 0;
|
||||
}
|
||||
|
||||
desc_text_final = NULL;
|
||||
if (desc_text)
|
||||
{
|
||||
if (comment[comment_length])
|
||||
{
|
||||
/* Not a C-string; create one. We might here allocate
|
||||
more than actually displayed but well, that
|
||||
shouldn't be a problem. */
|
||||
char *tmp = xtrymalloc (comment_length+1);
|
||||
if (!tmp)
|
||||
rc = gpg_error_from_errno (errno);
|
||||
else
|
||||
{
|
||||
memcpy (tmp, comment, comment_length);
|
||||
tmp[comment_length] = 0;
|
||||
rc = modify_description (desc_text, tmp, &desc_text_final);
|
||||
xfree (tmp);
|
||||
}
|
||||
}
|
||||
else
|
||||
rc = modify_description (desc_text, comment, &desc_text_final);
|
||||
}
|
||||
|
||||
if (!rc)
|
||||
{
|
||||
rc = unprotect (ctrl, desc_text_final, &buf, grip, cache_mode);
|
||||
if (rc)
|
||||
log_error ("failed to unprotect the secret key: %s\n",
|
||||
gpg_strerror (rc));
|
||||
}
|
||||
|
||||
gcry_sexp_release (comment_sexp);
|
||||
xfree (desc_text_final);
|
||||
}
|
||||
break;
|
||||
case PRIVATE_KEY_SHADOWED:
|
||||
if (shadow_info)
|
||||
{
|
||||
const unsigned char *s;
|
||||
size_t n;
|
||||
|
||||
rc = agent_get_shadow_info (buf, &s);
|
||||
if (!rc)
|
||||
{
|
||||
n = gcry_sexp_canon_len (s, 0, NULL,NULL);
|
||||
assert (n);
|
||||
*shadow_info = xtrymalloc (n);
|
||||
if (!*shadow_info)
|
||||
rc = out_of_core ();
|
||||
else
|
||||
{
|
||||
memcpy (*shadow_info, s, n);
|
||||
rc = 0;
|
||||
got_shadow_info = 1;
|
||||
}
|
||||
}
|
||||
if (rc)
|
||||
log_error ("get_shadow_info failed: %s\n", gpg_strerror (rc));
|
||||
}
|
||||
else
|
||||
rc = gpg_error (GPG_ERR_UNUSABLE_SECKEY);
|
||||
break;
|
||||
default:
|
||||
log_error ("invalid private key format\n");
|
||||
rc = gpg_error (GPG_ERR_BAD_SECKEY);
|
||||
break;
|
||||
}
|
||||
gcry_sexp_release (s_skey);
|
||||
s_skey = NULL;
|
||||
if (rc || got_shadow_info)
|
||||
{
|
||||
xfree (buf);
|
||||
return rc;
|
||||
}
|
||||
|
||||
buflen = gcry_sexp_canon_len (buf, 0, NULL, NULL);
|
||||
rc = gcry_sexp_sscan (&s_skey, &erroff, (char*)buf, buflen);
|
||||
wipememory (buf, buflen);
|
||||
xfree (buf);
|
||||
if (rc)
|
||||
{
|
||||
log_error ("failed to build S-Exp (off=%u): %s\n",
|
||||
(unsigned int)erroff, gpg_strerror (rc));
|
||||
return rc;
|
||||
}
|
||||
|
||||
*result = s_skey;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Return the public key for the keygrip GRIP. The result is stored
|
||||
at RESULT. This function extracts the public key from the private
|
||||
key database. On failure an error code is returned and NULL stored
|
||||
at RESULT. */
|
||||
gpg_error_t
|
||||
agent_public_key_from_file (ctrl_t ctrl,
|
||||
const unsigned char *grip,
|
||||
gcry_sexp_t *result)
|
||||
{
|
||||
int i, idx, rc;
|
||||
gcry_sexp_t s_skey;
|
||||
const char *algoname;
|
||||
gcry_sexp_t uri_sexp, comment_sexp;
|
||||
const char *uri, *comment;
|
||||
size_t uri_length, comment_length;
|
||||
char *format, *p;
|
||||
void *args[4+2+2+1]; /* Size is max. # of elements + 2 for uri + 2
|
||||
for comment + end-of-list. */
|
||||
int argidx;
|
||||
gcry_sexp_t list, l2;
|
||||
const char *name;
|
||||
const char *s;
|
||||
size_t n;
|
||||
const char *elems;
|
||||
gcry_mpi_t *array;
|
||||
|
||||
*result = NULL;
|
||||
|
||||
rc = read_key_file (grip, &s_skey);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
list = gcry_sexp_find_token (s_skey, "shadowed-private-key", 0 );
|
||||
if (!list)
|
||||
list = gcry_sexp_find_token (s_skey, "protected-private-key", 0 );
|
||||
if (!list)
|
||||
list = gcry_sexp_find_token (s_skey, "private-key", 0 );
|
||||
if (!list)
|
||||
{
|
||||
log_error ("invalid private key format\n");
|
||||
gcry_sexp_release (s_skey);
|
||||
return gpg_error (GPG_ERR_BAD_SECKEY);
|
||||
}
|
||||
|
||||
l2 = gcry_sexp_cadr (list);
|
||||
gcry_sexp_release (list);
|
||||
list = l2;
|
||||
name = gcry_sexp_nth_data (list, 0, &n);
|
||||
if (n==3 && !memcmp (name, "rsa", 3))
|
||||
{
|
||||
algoname = "rsa";
|
||||
elems = "ne";
|
||||
}
|
||||
else if (n==3 && !memcmp (name, "dsa", 3))
|
||||
{
|
||||
algoname = "dsa";
|
||||
elems = "pqgy";
|
||||
}
|
||||
else if (n==3 && !memcmp (name, "elg", 3))
|
||||
{
|
||||
algoname = "elg";
|
||||
elems = "pgy";
|
||||
}
|
||||
else
|
||||
{
|
||||
log_error ("unknown private key algorithm\n");
|
||||
gcry_sexp_release (list);
|
||||
gcry_sexp_release (s_skey);
|
||||
return gpg_error (GPG_ERR_BAD_SECKEY);
|
||||
}
|
||||
|
||||
/* Allocate an array for the parameters and copy them out of the
|
||||
secret key. FIXME: We should have a generic copy function. */
|
||||
array = xtrycalloc (strlen(elems) + 1, sizeof *array);
|
||||
if (!array)
|
||||
{
|
||||
rc = gpg_error_from_errno (errno);
|
||||
gcry_sexp_release (list);
|
||||
gcry_sexp_release (s_skey);
|
||||
return rc;
|
||||
}
|
||||
|
||||
for (idx=0, s=elems; *s; s++, idx++ )
|
||||
{
|
||||
l2 = gcry_sexp_find_token (list, s, 1);
|
||||
if (!l2)
|
||||
{
|
||||
/* Required parameter not found. */
|
||||
for (i=0; i<idx; i++)
|
||||
gcry_mpi_release (array[i]);
|
||||
xfree (array);
|
||||
gcry_sexp_release (list);
|
||||
gcry_sexp_release (s_skey);
|
||||
return gpg_error (GPG_ERR_BAD_SECKEY);
|
||||
}
|
||||
array[idx] = gcry_sexp_nth_mpi (l2, 1, GCRYMPI_FMT_USG);
|
||||
gcry_sexp_release (l2);
|
||||
if (!array[idx])
|
||||
{
|
||||
/* Required parameter is invalid. */
|
||||
for (i=0; i<idx; i++)
|
||||
gcry_mpi_release (array[i]);
|
||||
xfree (array);
|
||||
gcry_sexp_release (list);
|
||||
gcry_sexp_release (s_skey);
|
||||
return gpg_error (GPG_ERR_BAD_SECKEY);
|
||||
}
|
||||
}
|
||||
gcry_sexp_release (list);
|
||||
list = NULL;
|
||||
|
||||
uri = NULL;
|
||||
uri_length = 0;
|
||||
uri_sexp = gcry_sexp_find_token (s_skey, "uri", 0);
|
||||
if (uri_sexp)
|
||||
uri = gcry_sexp_nth_data (uri_sexp, 1, &uri_length);
|
||||
|
||||
comment = NULL;
|
||||
comment_length = 0;
|
||||
comment_sexp = gcry_sexp_find_token (s_skey, "comment", 0);
|
||||
if (comment_sexp)
|
||||
comment = gcry_sexp_nth_data (comment_sexp, 1, &comment_length);
|
||||
|
||||
gcry_sexp_release (s_skey);
|
||||
s_skey = NULL;
|
||||
|
||||
|
||||
/* FIXME: The following thing is pretty ugly code; we should
|
||||
investigate how to make it cleaner. Probably code to handle
|
||||
canonical S-expressions in a memory buffer is better suioted for
|
||||
such a task. After all that is what we do in protect.c. Neeed
|
||||
to find common patterns and write a straightformward API to use
|
||||
them. */
|
||||
assert (sizeof (size_t) <= sizeof (void*));
|
||||
|
||||
format = xtrymalloc (15+7*strlen (elems)+10+15+1+1);
|
||||
if (!format)
|
||||
{
|
||||
rc = gpg_error_from_errno (errno);
|
||||
for (i=0; array[i]; i++)
|
||||
gcry_mpi_release (array[i]);
|
||||
xfree (array);
|
||||
gcry_sexp_release (uri_sexp);
|
||||
gcry_sexp_release (comment_sexp);
|
||||
return rc;
|
||||
}
|
||||
|
||||
argidx = 0;
|
||||
p = stpcpy (stpcpy (format, "(public-key("), algoname);
|
||||
for (idx=0, s=elems; *s; s++, idx++ )
|
||||
{
|
||||
*p++ = '(';
|
||||
*p++ = *s;
|
||||
p = stpcpy (p, " %m)");
|
||||
assert (argidx < DIM (args));
|
||||
args[argidx++] = &array[idx];
|
||||
}
|
||||
*p++ = ')';
|
||||
if (uri)
|
||||
{
|
||||
p = stpcpy (p, "(uri %b)");
|
||||
assert (argidx+1 < DIM (args));
|
||||
args[argidx++] = (void *)uri_length;
|
||||
args[argidx++] = (void *)uri;
|
||||
}
|
||||
if (comment)
|
||||
{
|
||||
p = stpcpy (p, "(comment %b)");
|
||||
assert (argidx+1 < DIM (args));
|
||||
args[argidx++] = (void *)comment_length;
|
||||
args[argidx++] = (void*)comment;
|
||||
}
|
||||
*p++ = ')';
|
||||
*p = 0;
|
||||
assert (argidx < DIM (args));
|
||||
args[argidx] = NULL;
|
||||
|
||||
rc = gcry_sexp_build_array (&list, NULL, format, args);
|
||||
xfree (format);
|
||||
for (i=0; array[i]; i++)
|
||||
gcry_mpi_release (array[i]);
|
||||
xfree (array);
|
||||
gcry_sexp_release (uri_sexp);
|
||||
gcry_sexp_release (comment_sexp);
|
||||
|
||||
if (!rc)
|
||||
*result = list;
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Return the secret key as an S-Exp after locating it using the grip.
|
||||
Returns NULL if key is not available. 0 = key is available */
|
||||
int
|
||||
agent_key_available (const unsigned char *grip)
|
||||
{
|
||||
int i;
|
||||
char *fname;
|
||||
char hexgrip[40+4+1];
|
||||
|
||||
for (i=0; i < 20; i++)
|
||||
sprintf (hexgrip+2*i, "%02X", grip[i]);
|
||||
strcpy (hexgrip+40, ".key");
|
||||
|
||||
fname = make_filename (opt.homedir, GNUPG_PRIVATE_KEYS_DIR, hexgrip, NULL);
|
||||
i = !access (fname, R_OK)? 0 : -1;
|
||||
xfree (fname);
|
||||
return i;
|
||||
}
|
||||
|
||||
|
||||
|
255
agent/genkey.c
Normal file
@ -0,0 +1,255 @@
|
||||
/* pksign.c - Generate a keypair
|
||||
* Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of GnuPG.
|
||||
*
|
||||
* GnuPG is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* GnuPG is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
|
||||
* USA.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "agent.h"
|
||||
#include "i18n.h"
|
||||
|
||||
static int
|
||||
store_key (gcry_sexp_t private, const char *passphrase, int force)
|
||||
{
|
||||
int rc;
|
||||
unsigned char *buf;
|
||||
size_t len;
|
||||
unsigned char grip[20];
|
||||
|
||||
if ( !gcry_pk_get_keygrip (private, grip) )
|
||||
{
|
||||
log_error ("can't calculate keygrip\n");
|
||||
return gpg_error (GPG_ERR_GENERAL);
|
||||
}
|
||||
|
||||
len = gcry_sexp_sprint (private, GCRYSEXP_FMT_CANON, NULL, 0);
|
||||
assert (len);
|
||||
buf = gcry_malloc_secure (len);
|
||||
if (!buf)
|
||||
return out_of_core ();
|
||||
len = gcry_sexp_sprint (private, GCRYSEXP_FMT_CANON, buf, len);
|
||||
assert (len);
|
||||
|
||||
if (passphrase)
|
||||
{
|
||||
unsigned char *p;
|
||||
|
||||
rc = agent_protect (buf, passphrase, &p, &len);
|
||||
if (rc)
|
||||
{
|
||||
xfree (buf);
|
||||
return rc;
|
||||
}
|
||||
xfree (buf);
|
||||
buf = p;
|
||||
}
|
||||
|
||||
rc = agent_write_private_key (grip, buf, len, force);
|
||||
xfree (buf);
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* Callback function to compare the first entered PIN with the one
|
||||
currently being entered. */
|
||||
static int
|
||||
reenter_compare_cb (struct pin_entry_info_s *pi)
|
||||
{
|
||||
const char *pin1 = pi->check_cb_arg;
|
||||
|
||||
if (!strcmp (pin1, pi->pin))
|
||||
return 0; /* okay */
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Generate a new keypair according to the parameters given in
|
||||
KEYPARAM */
|
||||
int
|
||||
agent_genkey (CTRL ctrl, const char *keyparam, size_t keyparamlen,
|
||||
membuf_t *outbuf)
|
||||
{
|
||||
gcry_sexp_t s_keyparam, s_key, s_private, s_public;
|
||||
struct pin_entry_info_s *pi, *pi2;
|
||||
int rc;
|
||||
size_t len;
|
||||
char *buf;
|
||||
|
||||
rc = gcry_sexp_sscan (&s_keyparam, NULL, keyparam, keyparamlen);
|
||||
if (rc)
|
||||
{
|
||||
log_error ("failed to convert keyparam: %s\n", gpg_strerror (rc));
|
||||
return gpg_error (GPG_ERR_INV_DATA);
|
||||
}
|
||||
|
||||
/* Get the passphrase now, cause key generation may take a while. */
|
||||
{
|
||||
const char *text1 = _("Please enter the passphrase to%0A"
|
||||
"to protect your new key");
|
||||
const char *text2 = _("Please re-enter this passphrase");
|
||||
const char *initial_errtext = NULL;
|
||||
|
||||
pi = gcry_calloc_secure (2, sizeof (*pi) + 100);
|
||||
pi2 = pi + (sizeof *pi + 100);
|
||||
pi->max_length = 100;
|
||||
pi->max_tries = 3;
|
||||
pi2->max_length = 100;
|
||||
pi2->max_tries = 3;
|
||||
pi2->check_cb = reenter_compare_cb;
|
||||
pi2->check_cb_arg = pi->pin;
|
||||
|
||||
next_try:
|
||||
rc = agent_askpin (ctrl, text1, NULL, initial_errtext, pi);
|
||||
initial_errtext = NULL;
|
||||
if (!rc)
|
||||
{
|
||||
rc = agent_askpin (ctrl, text2, NULL, NULL, pi2);
|
||||
if (rc == -1)
|
||||
{ /* The re-entered one did not match and the user did not
|
||||
hit cancel. */
|
||||
initial_errtext = _("does not match - try again");
|
||||
goto next_try;
|
||||
}
|
||||
}
|
||||
if (rc)
|
||||
return rc;
|
||||
if (!*pi->pin)
|
||||
{
|
||||
xfree (pi);
|
||||
pi = NULL; /* User does not want a passphrase. */
|
||||
}
|
||||
}
|
||||
|
||||
rc = gcry_pk_genkey (&s_key, s_keyparam );
|
||||
gcry_sexp_release (s_keyparam);
|
||||
if (rc)
|
||||
{
|
||||
log_error ("key generation failed: %s\n", gpg_strerror (rc));
|
||||
xfree (pi);
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* break out the parts */
|
||||
s_private = gcry_sexp_find_token (s_key, "private-key", 0);
|
||||
if (!s_private)
|
||||
{
|
||||
log_error ("key generation failed: invalid return value\n");
|
||||
gcry_sexp_release (s_key);
|
||||
xfree (pi);
|
||||
return gpg_error (GPG_ERR_INV_DATA);
|
||||
}
|
||||
s_public = gcry_sexp_find_token (s_key, "public-key", 0);
|
||||
if (!s_public)
|
||||
{
|
||||
log_error ("key generation failed: invalid return value\n");
|
||||
gcry_sexp_release (s_private);
|
||||
gcry_sexp_release (s_key);
|
||||
xfree (pi);
|
||||
return gpg_error (GPG_ERR_INV_DATA);
|
||||
}
|
||||
gcry_sexp_release (s_key); s_key = NULL;
|
||||
|
||||
/* store the secret key */
|
||||
if (DBG_CRYPTO)
|
||||
log_debug ("storing private key\n");
|
||||
rc = store_key (s_private, pi? pi->pin:NULL, 0);
|
||||
xfree (pi); pi = NULL;
|
||||
gcry_sexp_release (s_private);
|
||||
if (rc)
|
||||
{
|
||||
gcry_sexp_release (s_public);
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* return the public key */
|
||||
if (DBG_CRYPTO)
|
||||
log_debug ("returning public key\n");
|
||||
len = gcry_sexp_sprint (s_public, GCRYSEXP_FMT_CANON, NULL, 0);
|
||||
assert (len);
|
||||
buf = xtrymalloc (len);
|
||||
if (!buf)
|
||||
{
|
||||
gpg_error_t tmperr = out_of_core ();
|
||||
gcry_sexp_release (s_private);
|
||||
gcry_sexp_release (s_public);
|
||||
return tmperr;
|
||||
}
|
||||
len = gcry_sexp_sprint (s_public, GCRYSEXP_FMT_CANON, buf, len);
|
||||
assert (len);
|
||||
put_membuf (outbuf, buf, len);
|
||||
gcry_sexp_release (s_public);
|
||||
xfree (buf);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Apply a new passpahrse to the key S_SKEY and store it. */
|
||||
int
|
||||
agent_protect_and_store (CTRL ctrl, gcry_sexp_t s_skey)
|
||||
{
|
||||
struct pin_entry_info_s *pi, *pi2;
|
||||
int rc;
|
||||
|
||||
{
|
||||
const char *text1 = _("Please enter the new passphrase");
|
||||
const char *text2 = _("Please re-enter this passphrase");
|
||||
const char *initial_errtext = NULL;
|
||||
|
||||
pi = gcry_calloc_secure (2, sizeof (*pi) + 100);
|
||||
pi2 = pi + (sizeof *pi + 100);
|
||||
pi->max_length = 100;
|
||||
pi->max_tries = 3;
|
||||
pi2->max_length = 100;
|
||||
pi2->max_tries = 3;
|
||||
pi2->check_cb = reenter_compare_cb;
|
||||
pi2->check_cb_arg = pi->pin;
|
||||
|
||||
next_try:
|
||||
rc = agent_askpin (ctrl, text1, NULL, initial_errtext, pi);
|
||||
if (!rc)
|
||||
{
|
||||
rc = agent_askpin (ctrl, text2, NULL, NULL, pi2);
|
||||
if (rc == -1)
|
||||
{ /* The re-entered one did not match and the user did not
|
||||
hit cancel. */
|
||||
initial_errtext = _("does not match - try again");
|
||||
goto next_try;
|
||||
}
|
||||
}
|
||||
if (rc)
|
||||
return rc;
|
||||
if (!*pi->pin)
|
||||
{
|
||||
xfree (pi);
|
||||
pi = NULL; /* User does not want a passphrase. */
|
||||
}
|
||||
}
|
||||
|
||||
rc = store_key (s_skey, pi? pi->pin:NULL, 1);
|
||||
xfree (pi);
|
||||
return 0;
|
||||
}
|
1686
agent/gpg-agent.c
Normal file
174
agent/keyformat.txt
Normal file
@ -0,0 +1,174 @@
|
||||
keyformat.txt (wk 2001-12-18)
|
||||
-----------------------------
|
||||
|
||||
|
||||
Some notes on the format of the secret keys used with gpg-agent.
|
||||
|
||||
Location of keys
|
||||
================
|
||||
The secret keys[1] are stored on a per file basis in a directory below
|
||||
the ~/.gnupg home directory. This directory is named
|
||||
|
||||
private-keys-v1.d
|
||||
|
||||
and should have permissions 700.
|
||||
|
||||
The secret keys are stored in files with a name matching the
|
||||
hexadecimal representation of the keygrip[2].
|
||||
|
||||
Unprotected Private Key Format
|
||||
==============================
|
||||
The content of the file is an S-Expression like the ones used with
|
||||
Libgcrypt. Here is an example of an unprotected file:
|
||||
|
||||
(private-key
|
||||
(rsa
|
||||
(n #00e0ce9..[some bytes not shown]..51#)
|
||||
(e #010001#)
|
||||
(d #046129F..[some bytes not shown]..81#)
|
||||
(p #00e861b..[some bytes not shown]..f1#)
|
||||
(q #00f7a7c..[some bytes not shown]..61#)
|
||||
(u #304559a..[some bytes not shown]..9b#)
|
||||
)
|
||||
(created-at timestamp)
|
||||
(uri http://foo.bar x-foo:whatever_you_want)
|
||||
(comment whatever)
|
||||
)
|
||||
|
||||
"comment", "created-at" and "uri" are optional. "comment" is
|
||||
currently used to keep track of ssh key comments. "created-at" is used
|
||||
to keep track of the creation time stamp used with OpenPGP keys; it is
|
||||
optional but required for some operations to calculate the fingerprint
|
||||
of the key. This timestamp should be a string with the number of
|
||||
seconds since Epoch or an ISO time string (yyyymmddThhmmss).
|
||||
|
||||
Actually this form should not be used for regular purposes and only
|
||||
accepted by gpg-agent with the configuration option:
|
||||
--allow-non-canonical-key-format. The regular way to represent the
|
||||
keys is in canonical representation[3]:
|
||||
|
||||
(private-key
|
||||
(rsa
|
||||
(n #00e0ce9..[some bytes not shown]..51#)
|
||||
(e #010001#)
|
||||
(d #046129F..[some bytes not shown]..81#)
|
||||
(p #00e861b..[some bytes not shown]..f1#)
|
||||
(q #00f7a7c..[some bytes not shown]..61#)
|
||||
(u #304559a..[some bytes not shown]..9b#)
|
||||
)
|
||||
(uri http://foo.bar x-foo:whatever_you_want)
|
||||
)
|
||||
|
||||
|
||||
Protected Private Key Format
|
||||
==============================
|
||||
A protected key is like this:
|
||||
|
||||
(protected-private-key
|
||||
(rsa
|
||||
(n #00e0ce9..[some bytes not shown]..51#)
|
||||
(e #010001#)
|
||||
(protected mode (parms) encrypted_octet_string)
|
||||
)
|
||||
(uri http://foo.bar x-foo:whatever_you_want)
|
||||
(comment whatever)
|
||||
)
|
||||
|
||||
|
||||
In this scheme the encrypted_octet_string is encrypted according to
|
||||
the algorithm described after the keyword protected; most protection
|
||||
algorithms need some parameters, which are given in a list before the
|
||||
encrypted_octet_string. The result of the decryption process is a
|
||||
list of the secret key parameters.
|
||||
|
||||
The only available protection mode for now is
|
||||
|
||||
openpgp-s2k3-sha1-aes-cbc
|
||||
|
||||
which describes an algorithm using using AES in CBC mode for
|
||||
encryption, SHA-1 for integrity protection and the String to Key
|
||||
algorithm 3 from OpenPGP (rfc2440).
|
||||
|
||||
Example:
|
||||
|
||||
(protected openpgp-s2k3-sha1-aes-cbc
|
||||
((sha1 16byte_salt no_of_iterations) 16byte_iv)
|
||||
encrypted_octet_string
|
||||
)
|
||||
|
||||
The encrypted_octet string should yield this S-Exp (in canonical
|
||||
representation) after decryption:
|
||||
|
||||
(
|
||||
(
|
||||
(d #046129F..[some bytes not shown]..81#)
|
||||
(p #00e861b..[some bytes not shown]..f1#)
|
||||
(q #00f7a7c..[some bytes not shown]..61#)
|
||||
(u #304559a..[some bytes not shown]..9b#)
|
||||
)
|
||||
(hash sha1 #...[hashvalue]...#)
|
||||
)
|
||||
|
||||
For padding reasons, random bytes are appended to this list - they can
|
||||
easily be stripped by looking for the end of the list.
|
||||
|
||||
The hash is calculated on the concatenation of the public key and
|
||||
secret key parameter lists: i.e it is required to hash the
|
||||
concatenation of these 6 canonical encoded lists for RSA, including
|
||||
the parenthesis and the algorithm keyword.
|
||||
|
||||
(rsa
|
||||
(n #00e0ce9..[some bytes not shown]..51#)
|
||||
(e #010001#)
|
||||
(d #046129F..[some bytes not shown]..81#)
|
||||
(p #00e861b..[some bytes not shown]..f1#)
|
||||
(q #00f7a7c..[some bytes not shown]..61#)
|
||||
(u #304559a..[some bytes not shown]..9b#)
|
||||
)
|
||||
|
||||
After decryption the hash must be recalculated and compared against
|
||||
the stored one - If they don't match the integrity of the key is not
|
||||
given.
|
||||
|
||||
|
||||
Shadowed Private Key Format
|
||||
============================
|
||||
To keep track of keys stored on IC cards we use a third format for
|
||||
private kyes which are called shadow keys as they are only a reference
|
||||
to keys stored on a token:
|
||||
|
||||
(shadowed-private-key
|
||||
(rsa
|
||||
(n #00e0ce9..[some bytes not shown]..51#)
|
||||
(e #010001#)
|
||||
(shadowed protocol (info))
|
||||
)
|
||||
(uri http://foo.bar x-foo:whatever_you_want)
|
||||
(comment whatever)
|
||||
)
|
||||
|
||||
The currently used protocol is "ti-v1" (token info version 1). The
|
||||
second list with the information has this layout:
|
||||
|
||||
(card_serial_number id_string_of_key)
|
||||
|
||||
More items may be added to the list.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Notes:
|
||||
======
|
||||
[1] I usually use the terms private and secret key exchangeable but prefer the
|
||||
term secret key because it can be visually be better distinguished
|
||||
from the term public key.
|
||||
|
||||
[2] The keygrip is a unique identifier for a key pair, it is
|
||||
independent of any protocol, so that the same key can be used with
|
||||
different protocols. PKCS-15 calls this a subjectKeyHash; it can be
|
||||
calculated using Libgcrypt's gcry_pk_get_keygrip ().
|
||||
|
||||
[3] Even when canonical representation are required we will show the
|
||||
S-expression here in a more readable representation.
|
436
agent/learncard.c
Normal file
@ -0,0 +1,436 @@
|
||||
/* learncard.c - Handle the LEARN command
|
||||
* Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of GnuPG.
|
||||
*
|
||||
* GnuPG is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* GnuPG is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
|
||||
* USA.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <assert.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include "agent.h"
|
||||
#include <assuan.h>
|
||||
|
||||
/* Structures used by the callback mechanism to convey information
|
||||
pertaining to key pairs. */
|
||||
struct keypair_info_s {
|
||||
struct keypair_info_s *next;
|
||||
int no_cert;
|
||||
char *id; /* points into grip */
|
||||
char hexgrip[1]; /* The keygrip (i.e. a hash over the public key
|
||||
parameters) formatted as a hex string.
|
||||
Allocated somewhat large to also act as
|
||||
memeory for the above ID field. */
|
||||
};
|
||||
typedef struct keypair_info_s *KEYPAIR_INFO;
|
||||
|
||||
struct kpinfo_cb_parm_s {
|
||||
int error;
|
||||
KEYPAIR_INFO info;
|
||||
};
|
||||
|
||||
|
||||
|
||||
/* Structures used by the callback mechanism to convey information
|
||||
pertaining to certificates. */
|
||||
struct certinfo_s {
|
||||
struct certinfo_s *next;
|
||||
int type;
|
||||
int done;
|
||||
char id[1];
|
||||
};
|
||||
typedef struct certinfo_s *CERTINFO;
|
||||
|
||||
struct certinfo_cb_parm_s {
|
||||
int error;
|
||||
CERTINFO info;
|
||||
};
|
||||
|
||||
|
||||
/* Structures used by the callback mechanism to convey assuan status
|
||||
lines. */
|
||||
struct sinfo_s {
|
||||
struct sinfo_s *next;
|
||||
char *data; /* Points into keyword. */
|
||||
char keyword[1];
|
||||
};
|
||||
typedef struct sinfo_s *SINFO;
|
||||
|
||||
struct sinfo_cb_parm_s {
|
||||
int error;;
|
||||
SINFO info;
|
||||
};
|
||||
|
||||
|
||||
/* Destructor for key information objects. */
|
||||
static void
|
||||
release_keypair_info (KEYPAIR_INFO info)
|
||||
{
|
||||
while (info)
|
||||
{
|
||||
KEYPAIR_INFO tmp = info->next;
|
||||
xfree (info);
|
||||
info = tmp;
|
||||
}
|
||||
}
|
||||
|
||||
/* Destructor for certificate information objects. */
|
||||
static void
|
||||
release_certinfo (CERTINFO info)
|
||||
{
|
||||
while (info)
|
||||
{
|
||||
CERTINFO tmp = info->next;
|
||||
xfree (info);
|
||||
info = tmp;
|
||||
}
|
||||
}
|
||||
|
||||
/* Destructor for status information objects. */
|
||||
static void
|
||||
release_sinfo (SINFO info)
|
||||
{
|
||||
while (info)
|
||||
{
|
||||
SINFO tmp = info->next;
|
||||
xfree (info);
|
||||
info = tmp;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* This callback is used by agent_card_learn and passed the content of
|
||||
all KEYPAIRINFO lines. It merely stores this data away */
|
||||
static void
|
||||
kpinfo_cb (void *opaque, const char *line)
|
||||
{
|
||||
struct kpinfo_cb_parm_s *parm = opaque;
|
||||
KEYPAIR_INFO item;
|
||||
char *p;
|
||||
|
||||
if (parm->error)
|
||||
return; /* no need to gather data after an error coccured */
|
||||
item = xtrycalloc (1, sizeof *item + strlen (line));
|
||||
if (!item)
|
||||
{
|
||||
parm->error = out_of_core ();
|
||||
return;
|
||||
}
|
||||
strcpy (item->hexgrip, line);
|
||||
for (p = item->hexgrip; hexdigitp (p); p++)
|
||||
;
|
||||
if (p == item->hexgrip && *p == 'X' && spacep (p+1))
|
||||
{
|
||||
item->no_cert = 1;
|
||||
p++;
|
||||
}
|
||||
else if ((p - item->hexgrip) != 40 || !spacep (p))
|
||||
{ /* not a 20 byte hex keygrip or not followed by a space */
|
||||
parm->error = gpg_error (GPG_ERR_INV_RESPONSE);
|
||||
xfree (item);
|
||||
return;
|
||||
}
|
||||
*p++ = 0;
|
||||
while (spacep (p))
|
||||
p++;
|
||||
item->id = p;
|
||||
while (*p && !spacep (p))
|
||||
p++;
|
||||
if (p == item->id)
|
||||
{ /* invalid ID string */
|
||||
parm->error = gpg_error (GPG_ERR_INV_RESPONSE);
|
||||
xfree (item);
|
||||
return;
|
||||
}
|
||||
*p = 0; /* ignore trailing stuff */
|
||||
|
||||
/* store it */
|
||||
item->next = parm->info;
|
||||
parm->info = item;
|
||||
}
|
||||
|
||||
|
||||
/* This callback is used by agent_card_learn and passed the content of
|
||||
all CERTINFO lines. It merely stores this data away */
|
||||
static void
|
||||
certinfo_cb (void *opaque, const char *line)
|
||||
{
|
||||
struct certinfo_cb_parm_s *parm = opaque;
|
||||
CERTINFO item;
|
||||
int type;
|
||||
char *p, *pend;
|
||||
|
||||
if (parm->error)
|
||||
return; /* no need to gather data after an error coccured */
|
||||
|
||||
type = strtol (line, &p, 10);
|
||||
while (spacep (p))
|
||||
p++;
|
||||
for (pend = p; *pend && !spacep (pend); pend++)
|
||||
;
|
||||
if (p == pend || !*p)
|
||||
{
|
||||
parm->error = gpg_error (GPG_ERR_INV_RESPONSE);
|
||||
return;
|
||||
}
|
||||
*pend = 0; /* ignore trailing stuff */
|
||||
|
||||
item = xtrycalloc (1, sizeof *item + strlen (p));
|
||||
if (!item)
|
||||
{
|
||||
parm->error = out_of_core ();
|
||||
return;
|
||||
}
|
||||
item->type = type;
|
||||
strcpy (item->id, p);
|
||||
/* store it */
|
||||
item->next = parm->info;
|
||||
parm->info = item;
|
||||
}
|
||||
|
||||
|
||||
/* This callback is used by agent_card_learn and passed the content of
|
||||
all SINFO lines. It merely stores this data away */
|
||||
static void
|
||||
sinfo_cb (void *opaque, const char *keyword, size_t keywordlen,
|
||||
const char *data)
|
||||
{
|
||||
struct sinfo_cb_parm_s *sparm = opaque;
|
||||
SINFO item;
|
||||
|
||||
if (sparm->error)
|
||||
return; /* no need to gather data after an error coccured */
|
||||
|
||||
item = xtrycalloc (1, sizeof *item + keywordlen + 1 + strlen (data));
|
||||
if (!item)
|
||||
{
|
||||
sparm->error = out_of_core ();
|
||||
return;
|
||||
}
|
||||
memcpy (item->keyword, keyword, keywordlen);
|
||||
item->data = item->keyword + keywordlen;
|
||||
*item->data = 0;
|
||||
item->data++;
|
||||
strcpy (item->data, data);
|
||||
/* store it */
|
||||
item->next = sparm->info;
|
||||
sparm->info = item;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static int
|
||||
send_cert_back (ctrl_t ctrl, const char *id, void *assuan_context)
|
||||
{
|
||||
int rc;
|
||||
char *derbuf;
|
||||
size_t derbuflen;
|
||||
|
||||
rc = agent_card_readcert (ctrl, id, &derbuf, &derbuflen);
|
||||
if (rc)
|
||||
{
|
||||
log_error ("error reading certificate: %s\n",
|
||||
gpg_strerror (rc));
|
||||
return rc;
|
||||
}
|
||||
|
||||
rc = assuan_send_data (assuan_context, derbuf, derbuflen);
|
||||
xfree (derbuf);
|
||||
if (!rc)
|
||||
rc = assuan_send_data (assuan_context, NULL, 0);
|
||||
if (!rc)
|
||||
rc = assuan_write_line (assuan_context, "END");
|
||||
if (rc)
|
||||
{
|
||||
log_error ("sending certificate failed: %s\n",
|
||||
assuan_strerror (rc));
|
||||
return map_assuan_err (rc);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Perform the learn operation. If ASSUAN_CONTEXT is not NULL all new
|
||||
certificates are send back via Assuan. */
|
||||
int
|
||||
agent_handle_learn (ctrl_t ctrl, void *assuan_context)
|
||||
{
|
||||
int rc;
|
||||
struct kpinfo_cb_parm_s parm;
|
||||
struct certinfo_cb_parm_s cparm;
|
||||
struct sinfo_cb_parm_s sparm;
|
||||
char *serialno = NULL;
|
||||
KEYPAIR_INFO item;
|
||||
SINFO sitem;
|
||||
unsigned char grip[20];
|
||||
char *p;
|
||||
int i;
|
||||
static int certtype_list[] = {
|
||||
101, /* trusted */
|
||||
102, /* useful */
|
||||
100, /* regular */
|
||||
/* We don't include 110 here because gpgsm can't handle it. */
|
||||
-1 /* end of list */
|
||||
};
|
||||
|
||||
|
||||
memset (&parm, 0, sizeof parm);
|
||||
memset (&cparm, 0, sizeof cparm);
|
||||
memset (&sparm, 0, sizeof sparm);
|
||||
|
||||
/* Check whether a card is present and get the serial number */
|
||||
rc = agent_card_serialno (ctrl, &serialno);
|
||||
if (rc)
|
||||
goto leave;
|
||||
|
||||
/* Now gather all the available info. */
|
||||
rc = agent_card_learn (ctrl, kpinfo_cb, &parm, certinfo_cb, &cparm,
|
||||
sinfo_cb, &sparm);
|
||||
if (!rc && (parm.error || cparm.error || sparm.error))
|
||||
rc = parm.error? parm.error : cparm.error? cparm.error : sparm.error;
|
||||
if (rc)
|
||||
{
|
||||
log_debug ("agent_card_learn failed: %s\n", gpg_strerror (rc));
|
||||
goto leave;
|
||||
}
|
||||
|
||||
log_info ("card has S/N: %s\n", serialno);
|
||||
|
||||
/* Pass on all the collected status information. */
|
||||
if (assuan_context)
|
||||
{
|
||||
for (sitem = sparm.info; sitem; sitem = sitem->next)
|
||||
{
|
||||
assuan_write_status (assuan_context, sitem->keyword, sitem->data);
|
||||
}
|
||||
}
|
||||
|
||||
/* Write out the certificates in a standard order. */
|
||||
for (i=0; certtype_list[i] != -1; i++)
|
||||
{
|
||||
CERTINFO citem;
|
||||
for (citem = cparm.info; citem; citem = citem->next)
|
||||
{
|
||||
if (certtype_list[i] != citem->type)
|
||||
continue;
|
||||
|
||||
if (opt.verbose)
|
||||
log_info (" id: %s (type=%d)\n",
|
||||
citem->id, citem->type);
|
||||
|
||||
if (assuan_context)
|
||||
{
|
||||
rc = send_cert_back (ctrl, citem->id, assuan_context);
|
||||
if (rc)
|
||||
goto leave;
|
||||
citem->done = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (item = parm.info; item; item = item->next)
|
||||
{
|
||||
unsigned char *pubkey, *shdkey;
|
||||
size_t n;
|
||||
|
||||
if (opt.verbose)
|
||||
log_info (" id: %s (grip=%s)\n", item->id, item->hexgrip);
|
||||
|
||||
if (item->no_cert)
|
||||
continue; /* No public key yet available. */
|
||||
|
||||
for (p=item->hexgrip, i=0; i < 20; p += 2, i++)
|
||||
grip[i] = xtoi_2 (p);
|
||||
|
||||
if (!agent_key_available (grip))
|
||||
continue; /* The key is already available. */
|
||||
|
||||
/* Unknown key - store it. */
|
||||
rc = agent_card_readkey (ctrl, item->id, &pubkey);
|
||||
if (rc)
|
||||
{
|
||||
log_debug ("agent_card_readkey failed: %s\n", gpg_strerror (rc));
|
||||
goto leave;
|
||||
}
|
||||
|
||||
{
|
||||
unsigned char *shadow_info = make_shadow_info (serialno, item->id);
|
||||
if (!shadow_info)
|
||||
{
|
||||
rc = gpg_error (GPG_ERR_ENOMEM);
|
||||
xfree (pubkey);
|
||||
goto leave;
|
||||
}
|
||||
rc = agent_shadow_key (pubkey, shadow_info, &shdkey);
|
||||
xfree (shadow_info);
|
||||
}
|
||||
xfree (pubkey);
|
||||
if (rc)
|
||||
{
|
||||
log_error ("shadowing the key failed: %s\n", gpg_strerror (rc));
|
||||
goto leave;
|
||||
}
|
||||
n = gcry_sexp_canon_len (shdkey, 0, NULL, NULL);
|
||||
assert (n);
|
||||
|
||||
rc = agent_write_private_key (grip, shdkey, n, 0);
|
||||
xfree (shdkey);
|
||||
if (rc)
|
||||
{
|
||||
log_error ("error writing key: %s\n", gpg_strerror (rc));
|
||||
goto leave;
|
||||
}
|
||||
|
||||
if (opt.verbose)
|
||||
log_info ("stored\n");
|
||||
|
||||
if (assuan_context)
|
||||
{
|
||||
CERTINFO citem;
|
||||
|
||||
/* only send the certificate if we have not done so before */
|
||||
for (citem = cparm.info; citem; citem = citem->next)
|
||||
{
|
||||
if (!strcmp (citem->id, item->id))
|
||||
break;
|
||||
}
|
||||
if (!citem)
|
||||
{
|
||||
rc = send_cert_back (ctrl, item->id, assuan_context);
|
||||
if (rc)
|
||||
goto leave;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
leave:
|
||||
xfree (serialno);
|
||||
release_keypair_info (parm.info);
|
||||
release_certinfo (cparm.info);
|
||||
release_sinfo (sparm.info);
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
2176
agent/minip12.c
Normal file
37
agent/minip12.h
Normal file
@ -0,0 +1,37 @@
|
||||
/* minip12.h - Global definitions for the minimal pkcs-12 implementation.
|
||||
* Copyright (C) 2002, 2003 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of GnuPG.
|
||||
*
|
||||
* GnuPG is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* GnuPG is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
|
||||
* USA.
|
||||
*/
|
||||
|
||||
#ifndef MINIP12_H
|
||||
#define MINIP12_H
|
||||
|
||||
#include <gcrypt.h>
|
||||
|
||||
gcry_mpi_t *p12_parse (const unsigned char *buffer, size_t length,
|
||||
const char *pw,
|
||||
void (*certcb)(void*, const unsigned char*, size_t),
|
||||
void *certcbarg);
|
||||
|
||||
unsigned char *p12_build (gcry_mpi_t *kparms,
|
||||
unsigned char *cert, size_t certlen,
|
||||
const char *pw, size_t *r_length);
|
||||
|
||||
|
||||
#endif /*MINIP12_H*/
|
142
agent/pkdecrypt.c
Normal file
@ -0,0 +1,142 @@
|
||||
/* pkdecrypt.c - public key decryption (well, acually using a secret key)
|
||||
* Copyright (C) 2001, 2003 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of GnuPG.
|
||||
*
|
||||
* GnuPG is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* GnuPG is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
|
||||
* USA.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <assert.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include "agent.h"
|
||||
|
||||
|
||||
/* DECRYPT the stuff in ciphertext which is expected to be a S-Exp.
|
||||
Try to get the key from CTRL and write the decoded stuff back to
|
||||
OUTFP. */
|
||||
int
|
||||
agent_pkdecrypt (CTRL ctrl, const char *desc_text,
|
||||
const unsigned char *ciphertext, size_t ciphertextlen,
|
||||
membuf_t *outbuf)
|
||||
{
|
||||
gcry_sexp_t s_skey = NULL, s_cipher = NULL, s_plain = NULL;
|
||||
unsigned char *shadow_info = NULL;
|
||||
int rc;
|
||||
char *buf = NULL;
|
||||
size_t len;
|
||||
|
||||
if (!ctrl->have_keygrip)
|
||||
{
|
||||
log_error ("speculative decryption not yet supported\n");
|
||||
rc = gpg_error (GPG_ERR_NO_SECKEY);
|
||||
goto leave;
|
||||
}
|
||||
|
||||
rc = gcry_sexp_sscan (&s_cipher, NULL, (char*)ciphertext, ciphertextlen);
|
||||
if (rc)
|
||||
{
|
||||
log_error ("failed to convert ciphertext: %s\n", gpg_strerror (rc));
|
||||
rc = gpg_error (GPG_ERR_INV_DATA);
|
||||
goto leave;
|
||||
}
|
||||
|
||||
if (DBG_CRYPTO)
|
||||
{
|
||||
log_printhex ("keygrip:", ctrl->keygrip, 20);
|
||||
log_printhex ("cipher: ", ciphertext, ciphertextlen);
|
||||
}
|
||||
rc = agent_key_from_file (ctrl, desc_text,
|
||||
ctrl->keygrip, &shadow_info,
|
||||
CACHE_MODE_NORMAL, &s_skey);
|
||||
if (rc)
|
||||
{
|
||||
log_error ("failed to read the secret key\n");
|
||||
goto leave;
|
||||
}
|
||||
|
||||
if (!s_skey)
|
||||
{ /* divert operation to the smartcard */
|
||||
|
||||
if (!gcry_sexp_canon_len (ciphertext, ciphertextlen, NULL, NULL))
|
||||
{
|
||||
rc = gpg_error (GPG_ERR_INV_SEXP);
|
||||
goto leave;
|
||||
}
|
||||
|
||||
rc = divert_pkdecrypt (ctrl, ciphertext, shadow_info, &buf, &len );
|
||||
if (rc)
|
||||
{
|
||||
log_error ("smartcard decryption failed: %s\n", gpg_strerror (rc));
|
||||
goto leave;
|
||||
}
|
||||
/* FIXME: Change the protocol to return a complete S-expression
|
||||
and not just a part. */
|
||||
{
|
||||
char tmpbuf[50];
|
||||
|
||||
sprintf (tmpbuf, "%u:", (unsigned int)len);
|
||||
put_membuf (outbuf, tmpbuf, strlen (tmpbuf));
|
||||
put_membuf (outbuf, buf, len);
|
||||
put_membuf (outbuf, "", 1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{ /* No smartcard, but a private key */
|
||||
/* if (DBG_CRYPTO ) */
|
||||
/* { */
|
||||
/* log_debug ("skey: "); */
|
||||
/* gcry_sexp_dump (s_skey); */
|
||||
/* } */
|
||||
|
||||
rc = gcry_pk_decrypt (&s_plain, s_cipher, s_skey);
|
||||
if (rc)
|
||||
{
|
||||
log_error ("decryption failed: %s\n", gpg_strerror (rc));
|
||||
goto leave;
|
||||
}
|
||||
|
||||
if (DBG_CRYPTO)
|
||||
{
|
||||
log_debug ("plain: ");
|
||||
gcry_sexp_dump (s_plain);
|
||||
}
|
||||
len = gcry_sexp_sprint (s_plain, GCRYSEXP_FMT_CANON, NULL, 0);
|
||||
assert (len);
|
||||
buf = xmalloc (len);
|
||||
len = gcry_sexp_sprint (s_plain, GCRYSEXP_FMT_CANON, buf, len);
|
||||
assert (len);
|
||||
put_membuf (outbuf, buf, len);
|
||||
}
|
||||
|
||||
|
||||
leave:
|
||||
gcry_sexp_release (s_skey);
|
||||
gcry_sexp_release (s_plain);
|
||||
gcry_sexp_release (s_cipher);
|
||||
xfree (buf);
|
||||
xfree (shadow_info);
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
205
agent/pksign.c
Normal file
@ -0,0 +1,205 @@
|
||||
/* pksign.c - public key signing (well, actually using a secret key)
|
||||
* Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of GnuPG.
|
||||
*
|
||||
* GnuPG is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* GnuPG is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
|
||||
* USA.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <assert.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include "agent.h"
|
||||
|
||||
|
||||
static int
|
||||
do_encode_md (const byte * md, size_t mdlen, int algo, gcry_sexp_t * r_hash,
|
||||
int raw_value)
|
||||
{
|
||||
gcry_sexp_t hash;
|
||||
int rc;
|
||||
|
||||
if (! raw_value)
|
||||
{
|
||||
const char *s;
|
||||
char tmp[16+1];
|
||||
int i;
|
||||
|
||||
s = gcry_md_algo_name (algo);
|
||||
if (s && strlen (s) < 16)
|
||||
{
|
||||
for (i=0; i < strlen (s); i++)
|
||||
tmp[i] = tolower (s[i]);
|
||||
tmp[i] = '\0';
|
||||
}
|
||||
|
||||
rc = gcry_sexp_build (&hash, NULL,
|
||||
"(data (flags pkcs1) (hash %s %b))",
|
||||
tmp, mdlen, md);
|
||||
}
|
||||
else
|
||||
{
|
||||
gcry_mpi_t mpi;
|
||||
|
||||
rc = gcry_mpi_scan (&mpi, GCRYMPI_FMT_USG, md, mdlen, NULL);
|
||||
if (! rc)
|
||||
{
|
||||
rc = gcry_sexp_build (&hash, NULL,
|
||||
"(data (flags raw) (value %m))",
|
||||
mpi);
|
||||
gcry_mpi_release (mpi);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
*r_hash = hash;
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
/* SIGN whatever information we have accumulated in CTRL and return
|
||||
the signature S-Expression. */
|
||||
int
|
||||
agent_pksign_do (ctrl_t ctrl, const char *desc_text,
|
||||
gcry_sexp_t *signature_sexp, cache_mode_t cache_mode)
|
||||
{
|
||||
gcry_sexp_t s_skey = NULL, s_sig = NULL;
|
||||
unsigned char *shadow_info = NULL;
|
||||
unsigned int rc = 0; /* FIXME: gpg-error? */
|
||||
|
||||
if (! ctrl->have_keygrip)
|
||||
return gpg_error (GPG_ERR_NO_SECKEY);
|
||||
|
||||
rc = agent_key_from_file (ctrl, desc_text, ctrl->keygrip,
|
||||
&shadow_info, cache_mode, &s_skey);
|
||||
if (rc)
|
||||
{
|
||||
log_error ("failed to read the secret key\n");
|
||||
goto leave;
|
||||
}
|
||||
|
||||
if (!s_skey)
|
||||
{
|
||||
/* Divert operation to the smartcard */
|
||||
|
||||
unsigned char *buf = NULL;
|
||||
size_t len = 0;
|
||||
|
||||
rc = divert_pksign (ctrl,
|
||||
ctrl->digest.value,
|
||||
ctrl->digest.valuelen,
|
||||
ctrl->digest.algo,
|
||||
shadow_info, &buf);
|
||||
if (rc)
|
||||
{
|
||||
log_error ("smartcard signing failed: %s\n", gpg_strerror (rc));
|
||||
goto leave;
|
||||
}
|
||||
len = gcry_sexp_canon_len (buf, 0, NULL, NULL);
|
||||
assert (len);
|
||||
|
||||
rc = gcry_sexp_sscan (&s_sig, NULL, (char*)buf, len);
|
||||
xfree (buf);
|
||||
if (rc)
|
||||
{
|
||||
log_error ("failed to convert sigbuf returned by divert_pksign "
|
||||
"into S-Exp: %s", gpg_strerror (rc));
|
||||
goto leave;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* No smartcard, but a private key */
|
||||
|
||||
gcry_sexp_t s_hash = NULL;
|
||||
|
||||
/* put the hash into a sexp */
|
||||
rc = do_encode_md (ctrl->digest.value,
|
||||
ctrl->digest.valuelen,
|
||||
ctrl->digest.algo,
|
||||
&s_hash,
|
||||
ctrl->digest.raw_value);
|
||||
if (rc)
|
||||
goto leave;
|
||||
|
||||
if (DBG_CRYPTO)
|
||||
{
|
||||
log_debug ("skey: ");
|
||||
gcry_sexp_dump (s_skey);
|
||||
}
|
||||
|
||||
/* sign */
|
||||
rc = gcry_pk_sign (&s_sig, s_hash, s_skey);
|
||||
gcry_sexp_release (s_hash);
|
||||
if (rc)
|
||||
{
|
||||
log_error ("signing failed: %s\n", gpg_strerror (rc));
|
||||
goto leave;
|
||||
}
|
||||
|
||||
if (DBG_CRYPTO)
|
||||
{
|
||||
log_debug ("result: ");
|
||||
gcry_sexp_dump (s_sig);
|
||||
}
|
||||
}
|
||||
|
||||
leave:
|
||||
|
||||
*signature_sexp = s_sig;
|
||||
|
||||
gcry_sexp_release (s_skey);
|
||||
xfree (shadow_info);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* SIGN whatever information we have accumulated in CTRL and write it
|
||||
back to OUTFP. */
|
||||
int
|
||||
agent_pksign (ctrl_t ctrl, const char *desc_text,
|
||||
membuf_t *outbuf, cache_mode_t cache_mode)
|
||||
{
|
||||
gcry_sexp_t s_sig = NULL;
|
||||
char *buf = NULL;
|
||||
size_t len = 0;
|
||||
int rc = 0;
|
||||
|
||||
rc = agent_pksign_do (ctrl, desc_text, &s_sig, cache_mode);
|
||||
if (rc)
|
||||
goto leave;
|
||||
|
||||
len = gcry_sexp_sprint (s_sig, GCRYSEXP_FMT_CANON, NULL, 0);
|
||||
assert (len);
|
||||
buf = xmalloc (len);
|
||||
len = gcry_sexp_sprint (s_sig, GCRYSEXP_FMT_CANON, buf, len);
|
||||
assert (len);
|
||||
|
||||
put_membuf (outbuf, buf, len);
|
||||
|
||||
leave:
|
||||
gcry_sexp_release (s_sig);
|
||||
xfree (buf);
|
||||
|
||||
return rc;
|
||||
}
|
337
agent/preset-passphrase.c
Normal file
@ -0,0 +1,337 @@
|
||||
/* preset-passphrase.c - A tool to preset a passphrase.
|
||||
* Copyright (C) 2004 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of GnuPG.
|
||||
*
|
||||
* GnuPG is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* GnuPG is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
|
||||
* USA.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stddef.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <assert.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#ifdef HAVE_LOCALE_H
|
||||
#include <locale.h>
|
||||
#endif
|
||||
#ifdef HAVE_LANGINFO_CODESET
|
||||
#include <langinfo.h>
|
||||
#endif
|
||||
#ifdef HAVE_DOSISH_SYSTEM
|
||||
#include <fcntl.h> /* for setmode() */
|
||||
#endif
|
||||
#ifdef HAVE_W32_SYSTEM
|
||||
#include <windows.h> /* To initialize the sockets. fixme */
|
||||
#endif
|
||||
|
||||
#define JNLIB_NEED_LOG_LOGV
|
||||
#include "agent.h"
|
||||
#include "minip12.h"
|
||||
#include "simple-pwquery.h"
|
||||
#include "i18n.h"
|
||||
#include "sysutils.h"
|
||||
|
||||
|
||||
enum cmd_and_opt_values
|
||||
{ aNull = 0,
|
||||
oVerbose = 'v',
|
||||
oPassphrase = 'P',
|
||||
|
||||
oPreset = 'c',
|
||||
oForget = 'f',
|
||||
|
||||
oNoVerbose = 500,
|
||||
|
||||
oHomedir,
|
||||
|
||||
aTest };
|
||||
|
||||
|
||||
static const char *opt_homedir;
|
||||
static const char *opt_passphrase;
|
||||
|
||||
static ARGPARSE_OPTS opts[] = {
|
||||
|
||||
{ 301, NULL, 0, N_("@Options:\n ") },
|
||||
|
||||
{ oVerbose, "verbose", 0, "verbose" },
|
||||
{ oPassphrase, "passphrase", 2, "|STRING|use passphrase STRING" },
|
||||
{ oPreset, "preset", 256, "preset passphrase"},
|
||||
{ oForget, "forget", 256, "forget passphrase"},
|
||||
|
||||
{ oHomedir, "homedir", 2, "@" },
|
||||
{0}
|
||||
};
|
||||
|
||||
|
||||
static const char *
|
||||
my_strusage (int level)
|
||||
{
|
||||
const char *p;
|
||||
switch (level)
|
||||
{
|
||||
case 11: p = "gpg-preset-passphrase (GnuPG)";
|
||||
break;
|
||||
case 13: p = VERSION; break;
|
||||
case 17: p = PRINTABLE_OS_NAME; break;
|
||||
case 19: p = _("Please report bugs to <" PACKAGE_BUGREPORT ">.\n");
|
||||
break;
|
||||
case 1:
|
||||
case 40:
|
||||
p = _("Usage: gpg-preset-passphrase [options] KEYGRIP (-h for help)\n");
|
||||
break;
|
||||
case 41:
|
||||
p = _("Syntax: gpg-preset-passphrase [options] KEYGRIP\n"
|
||||
"Password cache maintenance\n");
|
||||
break;
|
||||
|
||||
default: p = NULL;
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void
|
||||
i18n_init (void)
|
||||
{
|
||||
#ifdef USE_SIMPLE_GETTEXT
|
||||
set_gettext_file( PACKAGE_GT );
|
||||
#else
|
||||
#ifdef ENABLE_NLS
|
||||
setlocale (LC_ALL, "");
|
||||
bindtextdomain (PACKAGE_GT, LOCALEDIR);
|
||||
textdomain (PACKAGE_GT);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
static gpg_error_t
|
||||
map_spwq_error (int err)
|
||||
{
|
||||
switch (err)
|
||||
{
|
||||
case 0:
|
||||
return 0;
|
||||
case SPWQ_OUT_OF_CORE:
|
||||
return gpg_error_from_errno (ENOMEM);
|
||||
case SPWQ_IO_ERROR:
|
||||
return gpg_error_from_errno (EIO);
|
||||
case SPWQ_PROTOCOL_ERROR:
|
||||
return gpg_error (GPG_ERR_PROTOCOL_VIOLATION);
|
||||
case SPWQ_ERR_RESPONSE:
|
||||
return gpg_error (GPG_ERR_INV_RESPONSE);
|
||||
case SPWQ_NO_AGENT:
|
||||
return gpg_error (GPG_ERR_NO_AGENT);
|
||||
case SPWQ_SYS_ERROR:
|
||||
return gpg_error_from_errno (errno);
|
||||
case SPWQ_GENERAL_ERROR:
|
||||
default:
|
||||
return gpg_error (GPG_ERR_GENERAL);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Percent-Escape special characters. The string is valid until the
|
||||
next invocation of the function. */
|
||||
static char *
|
||||
make_hexstring (const char *src)
|
||||
{
|
||||
int len = 2 * strlen (src) + 1;
|
||||
char *dst;
|
||||
char *res;
|
||||
|
||||
res = dst = malloc (len);
|
||||
if (!dst)
|
||||
{
|
||||
log_error ("can not escape string: %s\n",
|
||||
gpg_strerror (gpg_error_from_errno (errno)));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#define _tohex(nr) ((nr) < 10 ? ((nr) + '0') : (((nr) - 10) + 'A'))
|
||||
#define tohex1(p) _tohex (*((unsigned char *) p) & 15)
|
||||
#define tohex2(p) _tohex ((*((unsigned char *) p) >> 4) & 15)
|
||||
|
||||
while (*src)
|
||||
{
|
||||
*(dst++) = tohex2 (src);
|
||||
*(dst++) = tohex1 (src);
|
||||
src++;
|
||||
}
|
||||
*dst = '\0';
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
preset_passphrase (const char *keygrip)
|
||||
{
|
||||
int rc;
|
||||
char *line;
|
||||
/* FIXME: Use secure memory. */
|
||||
char passphrase[500];
|
||||
char *passphrase_esc;
|
||||
|
||||
if (!opt_passphrase)
|
||||
{
|
||||
rc = read (0, passphrase, sizeof (passphrase) - 1);
|
||||
if (rc < 0)
|
||||
{
|
||||
log_error ("reading passphrase failed: %s\n",
|
||||
gpg_strerror (gpg_error_from_errno (errno)));
|
||||
return;
|
||||
}
|
||||
passphrase[rc] = '\0';
|
||||
line = strchr (passphrase, '\n');
|
||||
if (line)
|
||||
{
|
||||
if (line > passphrase && line[-1] == '\r')
|
||||
line--;
|
||||
*line = '\0';
|
||||
}
|
||||
|
||||
/* FIXME: How to handle empty passwords? */
|
||||
}
|
||||
|
||||
passphrase_esc = make_hexstring (opt_passphrase
|
||||
? opt_passphrase : passphrase);
|
||||
if (!passphrase_esc)
|
||||
{
|
||||
/* Error message printed by callee. */
|
||||
return;
|
||||
}
|
||||
|
||||
rc = asprintf (&line, "PRESET_PASSPHRASE %s -1 %s\n", keygrip,
|
||||
passphrase_esc);
|
||||
wipememory (passphrase_esc, strlen (passphrase_esc));
|
||||
free (passphrase_esc);
|
||||
|
||||
if (rc < 0)
|
||||
{
|
||||
log_error ("caching passphrase failed: %s\n",
|
||||
gpg_strerror (gpg_error_from_errno (errno)));
|
||||
return;
|
||||
}
|
||||
if (!opt_passphrase)
|
||||
wipememory (passphrase, sizeof (passphrase));
|
||||
|
||||
rc = map_spwq_error (simple_query (line));
|
||||
if (rc)
|
||||
{
|
||||
log_error ("caching passphrase failed: %s\n", gpg_strerror (rc));
|
||||
return;
|
||||
}
|
||||
|
||||
wipememory (line, strlen (line));
|
||||
free (line);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
forget_passphrase (const char *keygrip)
|
||||
{
|
||||
int rc;
|
||||
char *line;
|
||||
|
||||
rc = asprintf (&line, "CLEAR_PASSPHRASE %s\n", keygrip);
|
||||
if (rc < 0)
|
||||
{
|
||||
log_error ("clearing passphrase failed: %s\n",
|
||||
gpg_strerror (gpg_error_from_errno (errno)));
|
||||
return;
|
||||
}
|
||||
free (line);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
ARGPARSE_ARGS pargs;
|
||||
int cmd = 0;
|
||||
const char *keygrip = NULL;
|
||||
|
||||
set_strusage (my_strusage);
|
||||
log_set_prefix ("gpg-preset-passphrase", 1);
|
||||
|
||||
/* Try to auto set the character set. */
|
||||
set_native_charset (NULL);
|
||||
|
||||
#ifdef HAVE_W32_SYSTEM
|
||||
/* Fixme: Need to initialize the Windows sockets: This should be
|
||||
moved to another place and we should make sure that it won't get
|
||||
doen twice, like when Pth is used too. */
|
||||
{
|
||||
WSADATA wsadat;
|
||||
WSAStartup (0x202, &wsadat);
|
||||
}
|
||||
#endif
|
||||
|
||||
i18n_init ();
|
||||
|
||||
opt_homedir = default_homedir ();
|
||||
|
||||
pargs.argc = &argc;
|
||||
pargs.argv = &argv;
|
||||
pargs.flags= 1; /* (do not remove the args) */
|
||||
while (arg_parse (&pargs, opts) )
|
||||
{
|
||||
switch (pargs.r_opt)
|
||||
{
|
||||
case oVerbose: opt.verbose++; break;
|
||||
case oHomedir: opt_homedir = pargs.r.ret_str; break;
|
||||
|
||||
case oPreset: cmd = oPreset; break;
|
||||
case oForget: cmd = oForget; break;
|
||||
case oPassphrase: opt_passphrase = pargs.r.ret_str; break;
|
||||
|
||||
default : pargs.err = 2; break;
|
||||
}
|
||||
}
|
||||
if (log_get_errorcount(0))
|
||||
exit(2);
|
||||
|
||||
if (argc == 1)
|
||||
keygrip = *argv;
|
||||
else
|
||||
usage (1);
|
||||
|
||||
if (cmd == oPreset)
|
||||
preset_passphrase (keygrip);
|
||||
else if (cmd == oForget)
|
||||
forget_passphrase (keygrip);
|
||||
else
|
||||
log_error ("one of the options --preset or --forget must be given\n");
|
||||
|
||||
agent_exit (0);
|
||||
return 8; /*NOTREACHED*/
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
agent_exit (int rc)
|
||||
{
|
||||
rc = rc? rc : log_get_errorcount(0)? 2 : 0;
|
||||
exit (rc);
|
||||
}
|
1356
agent/protect-tool.c
Normal file
1024
agent/protect.c
Normal file
704
agent/query.c
Normal file
@ -0,0 +1,704 @@
|
||||
/* query.c - fork of the pinentry to query stuff from the user
|
||||
* Copyright (C) 2001, 2002, 2004 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of GnuPG.
|
||||
*
|
||||
* GnuPG is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* GnuPG is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
|
||||
* USA.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <assert.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/stat.h>
|
||||
#ifndef HAVE_W32_SYSTEM
|
||||
#include <sys/wait.h>
|
||||
#endif
|
||||
#include <pth.h>
|
||||
|
||||
#include "agent.h"
|
||||
#include "i18n.h"
|
||||
#include <assuan.h>
|
||||
|
||||
#ifdef _POSIX_OPEN_MAX
|
||||
#define MAX_OPEN_FDS _POSIX_OPEN_MAX
|
||||
#else
|
||||
#define MAX_OPEN_FDS 20
|
||||
#endif
|
||||
|
||||
|
||||
/* Because access to the pinentry must be serialized (it is and shall
|
||||
be a global mutual dialog) we should better timeout further
|
||||
requests after some time. 2 minutes seem to be a reasonable
|
||||
time. */
|
||||
#define LOCK_TIMEOUT (1*60)
|
||||
|
||||
/* The assuan context of the current pinentry. */
|
||||
static assuan_context_t entry_ctx;
|
||||
|
||||
/* The control variable of the connection owning the current pinentry.
|
||||
This is only valid if ENTRY_CTX is not NULL. Note, that we care
|
||||
only about the value of the pointer and that it should never be
|
||||
dereferenced. */
|
||||
static ctrl_t entry_owner;
|
||||
|
||||
/* A mutex used to serialize access to the pinentry. */
|
||||
static pth_mutex_t entry_lock;
|
||||
|
||||
/* The thread ID of the popup working thread. */
|
||||
static pth_t popup_tid;
|
||||
|
||||
/* A flag used in communication between the popup working thread and
|
||||
its stop function. */
|
||||
static int popup_finished;
|
||||
|
||||
|
||||
|
||||
/* Data to be passed to our callbacks, */
|
||||
struct entry_parm_s
|
||||
{
|
||||
int lines;
|
||||
size_t size;
|
||||
unsigned char *buffer;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
/* This function must be called once to initialize this module. This
|
||||
has to be done before a second thread is spawned. We can't do the
|
||||
static initialization because Pth emulation code might not be able
|
||||
to do a static init; in particular, it is not possible for W32. */
|
||||
void
|
||||
initialize_module_query (void)
|
||||
{
|
||||
static int initialized;
|
||||
|
||||
if (!initialized)
|
||||
{
|
||||
if (pth_mutex_init (&entry_lock))
|
||||
initialized = 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void
|
||||
dump_mutex_state (pth_mutex_t *m)
|
||||
{
|
||||
if (!(m->mx_state & PTH_MUTEX_INITIALIZED))
|
||||
log_printf ("not_initialized");
|
||||
else if (!(m->mx_state & PTH_MUTEX_LOCKED))
|
||||
log_printf ("not_locked");
|
||||
else
|
||||
log_printf ("locked tid=0x%lx count=%lu", (long)m->mx_owner, m->mx_count);
|
||||
}
|
||||
|
||||
|
||||
/* This function may be called to print infromation pertaining to the
|
||||
current state of this module to the log. */
|
||||
void
|
||||
agent_query_dump_state (void)
|
||||
{
|
||||
log_info ("agent_query_dump_state: entry_lock=");
|
||||
dump_mutex_state (&entry_lock);
|
||||
log_printf ("\n");
|
||||
log_info ("agent_query_dump_state: entry_ctx=%p pid=%ld popup_tid=%p\n",
|
||||
entry_ctx, (long)assuan_get_pid (entry_ctx), popup_tid);
|
||||
}
|
||||
|
||||
/* Called to make sure that a popup window owned by the current
|
||||
connection gets closed. */
|
||||
void
|
||||
agent_reset_query (ctrl_t ctrl)
|
||||
{
|
||||
if (entry_ctx && popup_tid && entry_owner == ctrl)
|
||||
{
|
||||
agent_popup_message_stop (ctrl);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Unlock the pinentry so that another thread can start one and
|
||||
disconnect that pinentry - we do this after the unlock so that a
|
||||
stalled pinentry does not block other threads. Fixme: We should
|
||||
have a timeout in Assuan for the disconnect operation. */
|
||||
static int
|
||||
unlock_pinentry (int rc)
|
||||
{
|
||||
assuan_context_t ctx = entry_ctx;
|
||||
|
||||
entry_ctx = NULL;
|
||||
if (!pth_mutex_release (&entry_lock))
|
||||
{
|
||||
log_error ("failed to release the entry lock\n");
|
||||
if (!rc)
|
||||
rc = gpg_error (GPG_ERR_INTERNAL);
|
||||
}
|
||||
assuan_disconnect (ctx);
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
/* To make sure we leave no secrets in our image after forking of the
|
||||
pinentry, we use this callback. */
|
||||
static void
|
||||
atfork_cb (void *opaque, int where)
|
||||
{
|
||||
if (!where)
|
||||
gcry_control (GCRYCTL_TERM_SECMEM);
|
||||
}
|
||||
|
||||
|
||||
/* Fork off the pin entry if this has not already been done. Note,
|
||||
that this function must always be used to aquire the lock for the
|
||||
pinentry - we will serialize _all_ pinentry calls.
|
||||
*/
|
||||
static int
|
||||
start_pinentry (ctrl_t ctrl)
|
||||
{
|
||||
int rc;
|
||||
const char *pgmname;
|
||||
ASSUAN_CONTEXT ctx;
|
||||
const char *argv[5];
|
||||
int no_close_list[3];
|
||||
int i;
|
||||
pth_event_t evt;
|
||||
|
||||
evt = pth_event (PTH_EVENT_TIME, pth_timeout (LOCK_TIMEOUT, 0));
|
||||
if (!pth_mutex_acquire (&entry_lock, 0, evt))
|
||||
{
|
||||
if (pth_event_occurred (evt))
|
||||
rc = gpg_error (GPG_ERR_TIMEOUT);
|
||||
else
|
||||
rc = gpg_error (GPG_ERR_INTERNAL);
|
||||
pth_event_free (evt, PTH_FREE_THIS);
|
||||
log_error (_("failed to acquire the pinentry lock: %s\n"),
|
||||
gpg_strerror (rc));
|
||||
return rc;
|
||||
}
|
||||
pth_event_free (evt, PTH_FREE_THIS);
|
||||
|
||||
entry_owner = ctrl;
|
||||
|
||||
if (entry_ctx)
|
||||
return 0;
|
||||
|
||||
if (opt.verbose)
|
||||
log_info ("starting a new PIN Entry\n");
|
||||
|
||||
if (fflush (NULL))
|
||||
{
|
||||
gpg_error_t tmperr = gpg_error (gpg_err_code_from_errno (errno));
|
||||
log_error ("error flushing pending output: %s\n", strerror (errno));
|
||||
return unlock_pinentry (tmperr);
|
||||
}
|
||||
|
||||
if (!opt.pinentry_program || !*opt.pinentry_program)
|
||||
opt.pinentry_program = GNUPG_DEFAULT_PINENTRY;
|
||||
if ( !(pgmname = strrchr (opt.pinentry_program, '/')))
|
||||
pgmname = opt.pinentry_program;
|
||||
else
|
||||
pgmname++;
|
||||
|
||||
argv[0] = pgmname;
|
||||
if (ctrl->display && !opt.keep_display)
|
||||
{
|
||||
argv[1] = "--display";
|
||||
argv[2] = ctrl->display;
|
||||
argv[3] = NULL;
|
||||
}
|
||||
else
|
||||
argv[1] = NULL;
|
||||
|
||||
i=0;
|
||||
if (!opt.running_detached)
|
||||
{
|
||||
if (log_get_fd () != -1)
|
||||
no_close_list[i++] = log_get_fd ();
|
||||
no_close_list[i++] = fileno (stderr);
|
||||
}
|
||||
no_close_list[i] = -1;
|
||||
|
||||
/* Connect to the pinentry and perform initial handshaking */
|
||||
rc = assuan_pipe_connect2 (&ctx, opt.pinentry_program, (char**)argv,
|
||||
no_close_list, atfork_cb, NULL);
|
||||
if (rc)
|
||||
{
|
||||
log_error ("can't connect to the PIN entry module: %s\n",
|
||||
assuan_strerror (rc));
|
||||
return unlock_pinentry (gpg_error (GPG_ERR_NO_PIN_ENTRY));
|
||||
}
|
||||
entry_ctx = ctx;
|
||||
|
||||
if (DBG_ASSUAN)
|
||||
log_debug ("connection to PIN entry established\n");
|
||||
|
||||
rc = assuan_transact (entry_ctx,
|
||||
opt.no_grab? "OPTION no-grab":"OPTION grab",
|
||||
NULL, NULL, NULL, NULL, NULL, NULL);
|
||||
if (rc)
|
||||
return unlock_pinentry (map_assuan_err (rc));
|
||||
if (ctrl->ttyname)
|
||||
{
|
||||
char *optstr;
|
||||
if (asprintf (&optstr, "OPTION ttyname=%s", ctrl->ttyname) < 0 )
|
||||
return unlock_pinentry (out_of_core ());
|
||||
rc = assuan_transact (entry_ctx, optstr, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL);
|
||||
free (optstr);
|
||||
if (rc)
|
||||
return unlock_pinentry (map_assuan_err (rc));
|
||||
}
|
||||
if (ctrl->ttytype)
|
||||
{
|
||||
char *optstr;
|
||||
if (asprintf (&optstr, "OPTION ttytype=%s", ctrl->ttytype) < 0 )
|
||||
return unlock_pinentry (out_of_core ());
|
||||
rc = assuan_transact (entry_ctx, optstr, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL);
|
||||
if (rc)
|
||||
return unlock_pinentry (map_assuan_err (rc));
|
||||
}
|
||||
if (ctrl->lc_ctype)
|
||||
{
|
||||
char *optstr;
|
||||
if (asprintf (&optstr, "OPTION lc-ctype=%s", ctrl->lc_ctype) < 0 )
|
||||
return unlock_pinentry (out_of_core ());
|
||||
rc = assuan_transact (entry_ctx, optstr, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL);
|
||||
if (rc)
|
||||
return unlock_pinentry (map_assuan_err (rc));
|
||||
}
|
||||
if (ctrl->lc_messages)
|
||||
{
|
||||
char *optstr;
|
||||
if (asprintf (&optstr, "OPTION lc-messages=%s", ctrl->lc_messages) < 0 )
|
||||
return unlock_pinentry (out_of_core ());
|
||||
rc = assuan_transact (entry_ctx, optstr, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL);
|
||||
if (rc)
|
||||
return unlock_pinentry (map_assuan_err (rc));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static AssuanError
|
||||
getpin_cb (void *opaque, const void *buffer, size_t length)
|
||||
{
|
||||
struct entry_parm_s *parm = opaque;
|
||||
|
||||
if (!buffer)
|
||||
return 0;
|
||||
|
||||
/* we expect the pin to fit on one line */
|
||||
if (parm->lines || length >= parm->size)
|
||||
return ASSUAN_Too_Much_Data;
|
||||
|
||||
/* fixme: we should make sure that the assuan buffer is allocated in
|
||||
secure memory or read the response byte by byte */
|
||||
memcpy (parm->buffer, buffer, length);
|
||||
parm->buffer[length] = 0;
|
||||
parm->lines++;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
all_digitsp( const char *s)
|
||||
{
|
||||
for (; *s && *s >= '0' && *s <= '9'; s++)
|
||||
;
|
||||
return !*s;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Call the Entry and ask for the PIN. We do check for a valid PIN
|
||||
number here and repeat it as long as we have invalid formed
|
||||
numbers. */
|
||||
int
|
||||
agent_askpin (ctrl_t ctrl,
|
||||
const char *desc_text, const char *prompt_text,
|
||||
const char *initial_errtext,
|
||||
struct pin_entry_info_s *pininfo)
|
||||
{
|
||||
int rc;
|
||||
char line[ASSUAN_LINELENGTH];
|
||||
struct entry_parm_s parm;
|
||||
const char *errtext = NULL;
|
||||
int is_pin = 0;
|
||||
|
||||
if (opt.batch)
|
||||
return 0; /* fixme: we should return BAD PIN */
|
||||
|
||||
if (!pininfo || pininfo->max_length < 1)
|
||||
return gpg_error (GPG_ERR_INV_VALUE);
|
||||
if (!desc_text && pininfo->min_digits)
|
||||
desc_text = _("Please enter your PIN, so that the secret key "
|
||||
"can be unlocked for this session");
|
||||
else if (!desc_text)
|
||||
desc_text = _("Please enter your passphrase, so that the secret key "
|
||||
"can be unlocked for this session");
|
||||
|
||||
if (prompt_text)
|
||||
is_pin = !!strstr (prompt_text, "PIN");
|
||||
else
|
||||
is_pin = desc_text && strstr (desc_text, "PIN");
|
||||
|
||||
rc = start_pinentry (ctrl);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
snprintf (line, DIM(line)-1, "SETDESC %s", desc_text);
|
||||
line[DIM(line)-1] = 0;
|
||||
rc = assuan_transact (entry_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
|
||||
if (rc)
|
||||
return unlock_pinentry (map_assuan_err (rc));
|
||||
|
||||
snprintf (line, DIM(line)-1, "SETPROMPT %s",
|
||||
prompt_text? prompt_text : is_pin? "PIN:" : "Passphrase:");
|
||||
line[DIM(line)-1] = 0;
|
||||
rc = assuan_transact (entry_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
|
||||
if (rc)
|
||||
return unlock_pinentry (map_assuan_err (rc));
|
||||
|
||||
|
||||
if (initial_errtext)
|
||||
{
|
||||
snprintf (line, DIM(line)-1, "SETERROR %s", initial_errtext);
|
||||
line[DIM(line)-1] = 0;
|
||||
rc = assuan_transact (entry_ctx, line,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL);
|
||||
if (rc)
|
||||
return unlock_pinentry (map_assuan_err (rc));
|
||||
}
|
||||
|
||||
for (;pininfo->failed_tries < pininfo->max_tries; pininfo->failed_tries++)
|
||||
{
|
||||
memset (&parm, 0, sizeof parm);
|
||||
parm.size = pininfo->max_length;
|
||||
parm.buffer = (unsigned char*)pininfo->pin;
|
||||
|
||||
if (errtext)
|
||||
{
|
||||
/* fixme: should we show the try count? It must be translated */
|
||||
snprintf (line, DIM(line)-1, "SETERROR %s (try %d of %d)",
|
||||
errtext, pininfo->failed_tries+1, pininfo->max_tries);
|
||||
line[DIM(line)-1] = 0;
|
||||
rc = assuan_transact (entry_ctx, line,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL);
|
||||
if (rc)
|
||||
return unlock_pinentry (map_assuan_err (rc));
|
||||
errtext = NULL;
|
||||
}
|
||||
|
||||
rc = assuan_transact (entry_ctx, "GETPIN", getpin_cb, &parm,
|
||||
NULL, NULL, NULL, NULL);
|
||||
if (rc == ASSUAN_Too_Much_Data)
|
||||
errtext = is_pin? _("PIN too long")
|
||||
: _("Passphrase too long");
|
||||
else if (rc)
|
||||
return unlock_pinentry (map_assuan_err (rc));
|
||||
|
||||
if (!errtext && pininfo->min_digits)
|
||||
{
|
||||
/* do some basic checks on the entered PIN. */
|
||||
if (!all_digitsp (pininfo->pin))
|
||||
errtext = _("Invalid characters in PIN");
|
||||
else if (pininfo->max_digits
|
||||
&& strlen (pininfo->pin) > pininfo->max_digits)
|
||||
errtext = _("PIN too long");
|
||||
else if (strlen (pininfo->pin) < pininfo->min_digits)
|
||||
errtext = _("PIN too short");
|
||||
}
|
||||
|
||||
if (!errtext && pininfo->check_cb)
|
||||
{
|
||||
/* More checks by utilizing the optional callback. */
|
||||
pininfo->cb_errtext = NULL;
|
||||
rc = pininfo->check_cb (pininfo);
|
||||
if (rc == -1 && pininfo->cb_errtext)
|
||||
errtext = pininfo->cb_errtext;
|
||||
else if (gpg_err_code (rc) == GPG_ERR_BAD_PASSPHRASE
|
||||
|| gpg_err_code (rc) == GPG_ERR_BAD_PIN)
|
||||
errtext = (is_pin? _("Bad PIN")
|
||||
: _("Bad Passphrase"));
|
||||
else if (rc)
|
||||
return unlock_pinentry (map_assuan_err (rc));
|
||||
}
|
||||
|
||||
if (!errtext)
|
||||
return unlock_pinentry (0); /* okay, got a PIN or passphrase */
|
||||
}
|
||||
|
||||
return unlock_pinentry (gpg_error (pininfo->min_digits? GPG_ERR_BAD_PIN
|
||||
: GPG_ERR_BAD_PASSPHRASE));
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Ask for the passphrase using the supplied arguments. The
|
||||
passphrase is returned in RETPASS as an hex encoded string to be
|
||||
freed by the caller */
|
||||
int
|
||||
agent_get_passphrase (ctrl_t ctrl,
|
||||
char **retpass, const char *desc, const char *prompt,
|
||||
const char *errtext)
|
||||
{
|
||||
|
||||
int rc;
|
||||
char line[ASSUAN_LINELENGTH];
|
||||
struct entry_parm_s parm;
|
||||
unsigned char *p;
|
||||
char *hexstring;
|
||||
int i;
|
||||
|
||||
*retpass = NULL;
|
||||
if (opt.batch)
|
||||
return gpg_error (GPG_ERR_BAD_PASSPHRASE);
|
||||
|
||||
rc = start_pinentry (ctrl);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
if (!prompt)
|
||||
prompt = desc && strstr (desc, "PIN")? "PIN": _("Passphrase");
|
||||
|
||||
|
||||
if (desc)
|
||||
snprintf (line, DIM(line)-1, "SETDESC %s", desc);
|
||||
else
|
||||
snprintf (line, DIM(line)-1, "RESET");
|
||||
line[DIM(line)-1] = 0;
|
||||
rc = assuan_transact (entry_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
|
||||
if (rc)
|
||||
return unlock_pinentry (map_assuan_err (rc));
|
||||
|
||||
snprintf (line, DIM(line)-1, "SETPROMPT %s", prompt);
|
||||
line[DIM(line)-1] = 0;
|
||||
rc = assuan_transact (entry_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
|
||||
if (rc)
|
||||
return unlock_pinentry (map_assuan_err (rc));
|
||||
|
||||
if (errtext)
|
||||
{
|
||||
snprintf (line, DIM(line)-1, "SETERROR %s", errtext);
|
||||
line[DIM(line)-1] = 0;
|
||||
rc = assuan_transact (entry_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
|
||||
if (rc)
|
||||
return unlock_pinentry (map_assuan_err (rc));
|
||||
}
|
||||
|
||||
memset (&parm, 0, sizeof parm);
|
||||
parm.size = ASSUAN_LINELENGTH/2 - 5;
|
||||
parm.buffer = gcry_malloc_secure (parm.size+10);
|
||||
if (!parm.buffer)
|
||||
return unlock_pinentry (out_of_core ());
|
||||
|
||||
assuan_begin_confidential (entry_ctx);
|
||||
rc = assuan_transact (entry_ctx, "GETPIN", getpin_cb, &parm, NULL, NULL, NULL, NULL);
|
||||
if (rc)
|
||||
{
|
||||
xfree (parm.buffer);
|
||||
return unlock_pinentry (map_assuan_err (rc));
|
||||
}
|
||||
|
||||
hexstring = gcry_malloc_secure (strlen ((char*)parm.buffer)*2+1);
|
||||
if (!hexstring)
|
||||
{
|
||||
gpg_error_t tmperr = out_of_core ();
|
||||
xfree (parm.buffer);
|
||||
return unlock_pinentry (tmperr);
|
||||
}
|
||||
|
||||
for (i=0, p=parm.buffer; *p; p++, i += 2)
|
||||
sprintf (hexstring+i, "%02X", *p);
|
||||
|
||||
xfree (parm.buffer);
|
||||
*retpass = hexstring;
|
||||
return unlock_pinentry (0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Pop up the PIN-entry, display the text and the prompt and ask the
|
||||
user to confirm this. We return 0 for success, ie. the user
|
||||
confirmed it, GPG_ERR_NOT_CONFIRMED for what the text says or an
|
||||
other error. */
|
||||
int
|
||||
agent_get_confirmation (ctrl_t ctrl,
|
||||
const char *desc, const char *ok, const char *cancel)
|
||||
{
|
||||
int rc;
|
||||
char line[ASSUAN_LINELENGTH];
|
||||
|
||||
rc = start_pinentry (ctrl);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
if (desc)
|
||||
snprintf (line, DIM(line)-1, "SETDESC %s", desc);
|
||||
else
|
||||
snprintf (line, DIM(line)-1, "RESET");
|
||||
line[DIM(line)-1] = 0;
|
||||
rc = assuan_transact (entry_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
|
||||
if (rc)
|
||||
return unlock_pinentry (map_assuan_err (rc));
|
||||
|
||||
if (ok)
|
||||
{
|
||||
snprintf (line, DIM(line)-1, "SETOK %s", ok);
|
||||
line[DIM(line)-1] = 0;
|
||||
rc = assuan_transact (entry_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
|
||||
if (rc)
|
||||
return unlock_pinentry (map_assuan_err (rc));
|
||||
}
|
||||
if (cancel)
|
||||
{
|
||||
snprintf (line, DIM(line)-1, "SETCANCEL %s", cancel);
|
||||
line[DIM(line)-1] = 0;
|
||||
rc = assuan_transact (entry_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
|
||||
if (rc)
|
||||
return unlock_pinentry (map_assuan_err (rc));
|
||||
}
|
||||
|
||||
rc = assuan_transact (entry_ctx, "CONFIRM", NULL, NULL, NULL, NULL, NULL, NULL);
|
||||
return unlock_pinentry (map_assuan_err (rc));
|
||||
}
|
||||
|
||||
|
||||
/* The thread running the popup message. */
|
||||
static void *
|
||||
popup_message_thread (void *arg)
|
||||
{
|
||||
assuan_transact (entry_ctx, "CONFIRM", NULL, NULL, NULL, NULL, NULL, NULL);
|
||||
popup_finished = 1;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/* Pop up a message window similar to the confirm one but keep it open
|
||||
until agent_popup_message_stop has been called. It is crucial for
|
||||
the caller to make sure that the stop function gets called as soon
|
||||
as the message is not anymore required becuase the message is
|
||||
system modal and all other attempts to use the pinentry will fail
|
||||
(after a timeout). */
|
||||
int
|
||||
agent_popup_message_start (ctrl_t ctrl, const char *desc,
|
||||
const char *ok_btn, const char *cancel_btn)
|
||||
{
|
||||
int rc;
|
||||
char line[ASSUAN_LINELENGTH];
|
||||
pth_attr_t tattr;
|
||||
|
||||
rc = start_pinentry (ctrl);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
if (desc)
|
||||
snprintf (line, DIM(line)-1, "SETDESC %s", desc);
|
||||
else
|
||||
snprintf (line, DIM(line)-1, "RESET");
|
||||
line[DIM(line)-1] = 0;
|
||||
rc = assuan_transact (entry_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
|
||||
if (rc)
|
||||
return unlock_pinentry (map_assuan_err (rc));
|
||||
|
||||
if (ok_btn)
|
||||
{
|
||||
snprintf (line, DIM(line)-1, "SETOK %s", ok_btn);
|
||||
line[DIM(line)-1] = 0;
|
||||
rc = assuan_transact (entry_ctx, line, NULL,NULL,NULL,NULL,NULL,NULL);
|
||||
if (rc)
|
||||
return unlock_pinentry (map_assuan_err (rc));
|
||||
}
|
||||
if (cancel_btn)
|
||||
{
|
||||
snprintf (line, DIM(line)-1, "SETCANCEL %s", cancel_btn);
|
||||
line[DIM(line)-1] = 0;
|
||||
rc = assuan_transact (entry_ctx, line, NULL,NULL,NULL,NULL,NULL,NULL);
|
||||
if (rc)
|
||||
return unlock_pinentry (map_assuan_err (rc));
|
||||
}
|
||||
|
||||
tattr = pth_attr_new();
|
||||
pth_attr_set (tattr, PTH_ATTR_JOINABLE, 1);
|
||||
pth_attr_set (tattr, PTH_ATTR_STACK_SIZE, 256*1024);
|
||||
pth_attr_set (tattr, PTH_ATTR_NAME, "popup-message");
|
||||
|
||||
popup_finished = 0;
|
||||
popup_tid = pth_spawn (tattr, popup_message_thread, NULL);
|
||||
if (!popup_tid)
|
||||
{
|
||||
rc = gpg_error_from_errno (errno);
|
||||
log_error ("error spawning popup message handler: %s\n",
|
||||
strerror (errno) );
|
||||
pth_attr_destroy (tattr);
|
||||
return unlock_pinentry (rc);
|
||||
}
|
||||
pth_attr_destroy (tattr);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Close a popup window. */
|
||||
void
|
||||
agent_popup_message_stop (ctrl_t ctrl)
|
||||
{
|
||||
int rc;
|
||||
pid_t pid;
|
||||
|
||||
if (!popup_tid || !entry_ctx)
|
||||
{
|
||||
log_debug ("agent_popup_message_stop called with no active popup\n");
|
||||
return;
|
||||
}
|
||||
|
||||
pid = assuan_get_pid (entry_ctx);
|
||||
if (pid == (pid_t)(-1))
|
||||
; /* No pid available can't send a kill. */
|
||||
else if (popup_finished)
|
||||
; /* Already finished and ready for joining. */
|
||||
else if (pid && ((rc=waitpid (pid, NULL, WNOHANG))==-1 || (rc == pid)) )
|
||||
{ /* The daemon already died. No need to send a kill. However
|
||||
because we already waited for the process, we need to tell
|
||||
assuan that it should not wait again (done by
|
||||
unlock_pinentry). */
|
||||
if (rc == pid)
|
||||
assuan_set_flag (entry_ctx, ASSUAN_NO_WAITPID, 1);
|
||||
}
|
||||
else
|
||||
kill (pid, SIGINT);
|
||||
|
||||
/* Now wait for the thread to terminate. */
|
||||
rc = pth_join (popup_tid, NULL);
|
||||
if (!rc)
|
||||
log_debug ("agent_popup_message_stop: pth_join failed: %s\n",
|
||||
strerror (errno));
|
||||
popup_tid = NULL;
|
||||
entry_owner = NULL;
|
||||
|
||||
/* Now we can close the connection. */
|
||||
unlock_pinentry (0);
|
||||
}
|
||||
|
||||
|
309
agent/t-protect.c
Normal file
@ -0,0 +1,309 @@
|
||||
/* t-protect.c - Module tests for protect.c
|
||||
* Copyright (C) 2005 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of GnuPG.
|
||||
*
|
||||
* GnuPG is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* GnuPG is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
|
||||
* USA.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "agent.h"
|
||||
|
||||
|
||||
#define pass() do { ; } while(0)
|
||||
#define fail() do { fprintf (stderr, "%s:%d: test failed\n",\
|
||||
__FILE__,__LINE__); \
|
||||
exit (1); \
|
||||
} while(0)
|
||||
|
||||
|
||||
static void
|
||||
test_agent_protect (void)
|
||||
{
|
||||
/* Protect the key encoded in canonical format in PLAINKEY. We assume
|
||||
a valid S-Exp here. */
|
||||
|
||||
unsigned int i;
|
||||
int ret;
|
||||
struct key_spec
|
||||
{
|
||||
const char *string;
|
||||
};
|
||||
/* Valid RSA key. */
|
||||
struct key_spec key_rsa_valid =
|
||||
{
|
||||
"\x28\x31\x31\x3A\x70\x72\x69\x76\x61\x74\x65\x2D\x6B\x65\x79\x28\x33\x3A\x72\x73"
|
||||
"\x61\x28\x31\x3A\x6E\x31\x32\x39\x3A\x00\xB6\xB5\x09\x59\x6A\x9E\xCA\xBC\x93\x92"
|
||||
"\x12\xF8\x91\xE6\x56\xA6\x26\xBA\x07\xDA\x85\x21\xA9\xCA\xD4\xC0\x8E\x64\x0C\x04"
|
||||
"\x05\x2F\xBB\x87\xF4\x24\xEF\x1A\x02\x75\xA4\x8A\x92\x99\xAC\x9D\xB6\x9A\xBE\x3D"
|
||||
"\x01\x24\xE6\xC7\x56\xB1\xF7\xDF\xB9\xB8\x42\xD6\x25\x1A\xEA\x6E\xE8\x53\x90\x49"
|
||||
"\x5C\xAD\xA7\x3D\x67\x15\x37\xFC\xE5\x85\x0A\x93\x2F\x32\xBA\xB6\x0A\xB1\xAC\x1F"
|
||||
"\x85\x2C\x1F\x83\xC6\x25\xE7\xA7\xD7\x0C\xDA\x9E\xF1\x6D\x5C\x8E\x47\x73\x9D\x77"
|
||||
"\xDF\x59\x26\x1A\xBE\x84\x54\x80\x7F\xF4\x41\xE1\x43\xFB\xD3\x7F\x85\x45\x29\x28"
|
||||
"\x31\x3A\x65\x33\x3A\x01\x00\x01\x29\x28\x31\x3A\x64\x31\x32\x38\x3A\x07\x7A\xD3"
|
||||
"\xDE\x28\x42\x45\xF4\x80\x6A\x1B\x82\xB7\x9E\x61\x6F\xBD\xE8\x21\xC8\x2D\x69\x1A"
|
||||
"\x65\x66\x5E\x57\xB5\xFA\xD3\xF3\x4E\x67\xF4\x01\xE7\xBD\x2E\x28\x69\x9E\x89\xD9"
|
||||
"\xC4\x96\xCF\x82\x19\x45\xAE\x83\xAC\x7A\x12\x31\x17\x6A\x19\x6B\xA6\x02\x7E\x77"
|
||||
"\xD8\x57\x89\x05\x5D\x50\x40\x4A\x7A\x2A\x95\xB1\x51\x2F\x91\xF1\x90\xBB\xAE\xF7"
|
||||
"\x30\xED\x55\x0D\x22\x7D\x51\x2F\x89\xC0\xCD\xB3\x1A\xC0\x6F\xA9\xA1\x95\x03\xDD"
|
||||
"\xF6\xB6\x6D\x0B\x42\xB9\x69\x1B\xFD\x61\x40\xEC\x17\x20\xFF\xC4\x8A\xE0\x0C\x34"
|
||||
"\x79\x6D\xC8\x99\xE5\x29\x28\x31\x3A\x70\x36\x35\x3A\x00\xD5\x86\xC7\x8E\x5F\x1B"
|
||||
"\x4B\xF2\xE7\xCD\x7A\x04\xCA\x09\x19\x11\x70\x6F\x19\x78\x8B\x93\xE4\x4E\xE2\x0A"
|
||||
"\xAF\x46\x2E\x83\x63\xE9\x8A\x72\x25\x3E\xD8\x45\xCC\xBF\x24\x81\xBB\x35\x1E\x85"
|
||||
"\x57\xC8\x5B\xCF\xFF\x0D\xAB\xDB\xFF\x8E\x26\xA7\x9A\x09\x38\x09\x6F\x27\x29\x28"
|
||||
"\x31\x3A\x71\x36\x35\x3A\x00\xDB\x0C\xDF\x60\xF2\x6F\x2A\x29\x6C\x88\xD6\xBF\x9F"
|
||||
"\x8E\x5B\xE4\x5C\x0D\xDD\x71\x3C\x96\xCC\x73\xEB\xCB\x48\xB0\x61\x74\x09\x43\xF2"
|
||||
"\x1D\x2A\x93\xD6\xE4\x2A\x72\x11\xE7\xF0\x2A\x95\xDC\xED\x6C\x39\x0A\x67\xAD\x21"
|
||||
"\xEC\xF7\x39\xAE\x8A\x0C\xA4\x6F\xF2\xEB\xB3\x29\x28\x31\x3A\x75\x36\x34\x3A\x33"
|
||||
"\x14\x91\x95\xF1\x69\x12\xDB\x20\xA4\x8D\x02\x0D\xBC\x3B\x9E\x38\x81\xB3\x9D\x72"
|
||||
"\x2B\xF7\x93\x78\xF6\x34\x0F\x43\x14\x8A\x6E\x9F\xC5\xF5\x3E\x28\x53\xB7\x38\x7B"
|
||||
"\xA4\x44\x3B\xA5\x3A\x52\xFC\xA8\x17\x3D\xE6\xE8\x5B\x42\xF9\x78\x3D\x4A\x78\x17"
|
||||
"\xD0\x68\x0B\x29\x29\x29\x00"
|
||||
};
|
||||
/* This RSA key is missing the last closing brace. */
|
||||
struct key_spec key_rsa_bogus_0 =
|
||||
{
|
||||
"\x28\x31\x31\x3A\x70\x72\x69\x76\x61\x74\x65\x2D\x6B\x65\x79\x28\x33\x3A\x72\x73"
|
||||
"\x61\x28\x31\x3A\x6E\x31\x32\x39\x3A\x00\xB6\xB5\x09\x59\x6A\x9E\xCA\xBC\x93\x92"
|
||||
"\x12\xF8\x91\xE6\x56\xA6\x26\xBA\x07\xDA\x85\x21\xA9\xCA\xD4\xC0\x8E\x64\x0C\x04"
|
||||
"\x05\x2F\xBB\x87\xF4\x24\xEF\x1A\x02\x75\xA4\x8A\x92\x99\xAC\x9D\xB6\x9A\xBE\x3D"
|
||||
"\x01\x24\xE6\xC7\x56\xB1\xF7\xDF\xB9\xB8\x42\xD6\x25\x1A\xEA\x6E\xE8\x53\x90\x49"
|
||||
"\x5C\xAD\xA7\x3D\x67\x15\x37\xFC\xE5\x85\x0A\x93\x2F\x32\xBA\xB6\x0A\xB1\xAC\x1F"
|
||||
"\x85\x2C\x1F\x83\xC6\x25\xE7\xA7\xD7\x0C\xDA\x9E\xF1\x6D\x5C\x8E\x47\x73\x9D\x77"
|
||||
"\xDF\x59\x26\x1A\xBE\x84\x54\x80\x7F\xF4\x41\xE1\x43\xFB\xD3\x7F\x85\x45\x29\x28"
|
||||
"\x31\x3A\x65\x33\x3A\x01\x00\x01\x29\x28\x31\x3A\x64\x31\x32\x38\x3A\x07\x7A\xD3"
|
||||
"\xDE\x28\x42\x45\xF4\x80\x6A\x1B\x82\xB7\x9E\x61\x6F\xBD\xE8\x21\xC8\x2D\x69\x1A"
|
||||
"\x65\x66\x5E\x57\xB5\xFA\xD3\xF3\x4E\x67\xF4\x01\xE7\xBD\x2E\x28\x69\x9E\x89\xD9"
|
||||
"\xC4\x96\xCF\x82\x19\x45\xAE\x83\xAC\x7A\x12\x31\x17\x6A\x19\x6B\xA6\x02\x7E\x77"
|
||||
"\xD8\x57\x89\x05\x5D\x50\x40\x4A\x7A\x2A\x95\xB1\x51\x2F\x91\xF1\x90\xBB\xAE\xF7"
|
||||
"\x30\xED\x55\x0D\x22\x7D\x51\x2F\x89\xC0\xCD\xB3\x1A\xC0\x6F\xA9\xA1\x95\x03\xDD"
|
||||
"\xF6\xB6\x6D\x0B\x42\xB9\x69\x1B\xFD\x61\x40\xEC\x17\x20\xFF\xC4\x8A\xE0\x0C\x34"
|
||||
"\x79\x6D\xC8\x99\xE5\x29\x28\x31\x3A\x70\x36\x35\x3A\x00\xD5\x86\xC7\x8E\x5F\x1B"
|
||||
"\x4B\xF2\xE7\xCD\x7A\x04\xCA\x09\x19\x11\x70\x6F\x19\x78\x8B\x93\xE4\x4E\xE2\x0A"
|
||||
"\xAF\x46\x2E\x83\x63\xE9\x8A\x72\x25\x3E\xD8\x45\xCC\xBF\x24\x81\xBB\x35\x1E\x85"
|
||||
"\x57\xC8\x5B\xCF\xFF\x0D\xAB\xDB\xFF\x8E\x26\xA7\x9A\x09\x38\x09\x6F\x27\x29\x28"
|
||||
"\x31\x3A\x71\x36\x35\x3A\x00\xDB\x0C\xDF\x60\xF2\x6F\x2A\x29\x6C\x88\xD6\xBF\x9F"
|
||||
"\x8E\x5B\xE4\x5C\x0D\xDD\x71\x3C\x96\xCC\x73\xEB\xCB\x48\xB0\x61\x74\x09\x43\xF2"
|
||||
"\x1D\x2A\x93\xD6\xE4\x2A\x72\x11\xE7\xF0\x2A\x95\xDC\xED\x6C\x39\x0A\x67\xAD\x21"
|
||||
"\xEC\xF7\x39\xAE\x8A\x0C\xA4\x6F\xF2\xEB\xB3\x29\x28\x31\x3A\x75\x36\x34\x3A\x33"
|
||||
"\x14\x91\x95\xF1\x69\x12\xDB\x20\xA4\x8D\x02\x0D\xBC\x3B\x9E\x38\x81\xB3\x9D\x72"
|
||||
"\x2B\xF7\x93\x78\xF6\x34\x0F\x43\x14\x8A\x6E\x9F\xC5\xF5\x3E\x28\x53\xB7\x38\x7B"
|
||||
"\xA4\x44\x3B\xA5\x3A\x52\xFC\xA8\x17\x3D\xE6\xE8\x5B\x42\xF9\x78\x3D\x4A\x78\x17"
|
||||
"\xD0\x68\x0B\x29\x29\x00"
|
||||
};
|
||||
/* This RSA key is the `e' value. */
|
||||
struct key_spec key_rsa_bogus_1 =
|
||||
{
|
||||
"\x28\x31\x31\x3A\x70\x72\x69\x76\x61\x74\x65\x2D\x6B\x65\x79\x28\x33\x3A\x72\x73"
|
||||
"\x61\x28\x31\x3A\x6E\x31\x32\x39\x3A\x00\xA8\x80\xB6\x71\xF4\x95\x9F\x49\x84\xED"
|
||||
"\xC1\x1D\x5F\xFF\xED\x14\x7B\x9C\x6A\x62\x0B\x7B\xE2\x3E\x41\x48\x49\x85\xF5\x64"
|
||||
"\x50\x04\x9D\x30\xFC\x84\x1F\x01\xC3\xC3\x15\x03\x48\x6D\xFE\x59\x0B\xB0\xD0\x3E"
|
||||
"\x68\x8A\x05\x7A\x62\xB0\xB9\x6E\xC5\xD2\xA8\xEE\x0C\x6B\xDE\x5E\x3D\x8E\xE8\x8F"
|
||||
"\xB3\xAE\x86\x99\x7E\xDE\x2B\xC2\x4D\x60\x51\xDB\xB1\x2C\xD0\x38\xEC\x88\x62\x3E"
|
||||
"\xA9\xDD\x11\x53\x04\x17\xE4\xF2\x07\x50\xDC\x44\xED\x14\xF5\x0B\xAB\x9C\xBC\x24"
|
||||
"\xC6\xCB\xAD\x0F\x05\x25\x94\xE2\x73\xEB\x14\xD5\xEE\x5E\x18\xF0\x40\x31\x29\x28"
|
||||
"\x31\x3A\x64\x31\x32\x38\x3A\x40\xD0\x55\x9D\x2A\xA7\xBC\xBF\xE2\x3E\x33\x98\x71"
|
||||
"\x7B\x37\x3D\xB8\x38\x57\xA1\x43\xEA\x90\x81\x42\xCA\x23\xE1\xBF\x9C\xA8\xBC\xC5"
|
||||
"\x9B\xF8\x9D\x77\x71\xCD\xD3\x85\x8B\x20\x3A\x92\xE9\xBC\x79\xF3\xF7\xF5\x6D\x15"
|
||||
"\xA3\x58\x3F\xC2\xEB\xED\x72\xD4\xE0\xCF\xEC\xB3\xEC\xEB\x09\xEA\x1E\x72\x6A\xBA"
|
||||
"\x95\x82\x2C\x7E\x30\x95\x66\x3F\xA8\x2D\x40\x0F\x7A\x12\x4E\xF0\x71\x0F\x97\xDB"
|
||||
"\x81\xE4\x39\x6D\x24\x58\xFA\xAB\x3A\x36\x73\x63\x01\x77\x42\xC7\x9A\xEA\x87\xDA"
|
||||
"\x93\x8F\x6C\x64\xAD\x9E\xF0\xCA\xA2\x89\xA4\x0E\xB3\x25\x73\x29\x28\x31\x3A\x70"
|
||||
"\x36\x35\x3A\x00\xC3\xF7\x37\x3F\x9D\x93\xEC\xC7\x5E\x4C\xB5\x73\x29\x62\x35\x80"
|
||||
"\xC6\x7C\x1B\x1E\x68\x5F\x92\x56\x77\x0A\xE2\x8E\x95\x74\x87\xA5\x2F\x83\x2D\xF7"
|
||||
"\xA1\xC2\x78\x54\x18\x6E\xDE\x35\xF0\x9F\x7A\xCA\x80\x5C\x83\x5C\x44\xAD\x8B\xE7"
|
||||
"\x5B\xE2\x63\x7D\x6A\xC7\x98\x97\x29\x28\x31\x3A\x71\x36\x35\x3A\x00\xDC\x1F\xB1"
|
||||
"\xB3\xD8\x13\xE0\x09\x19\xFD\x1C\x58\xA1\x2B\x02\xB4\xC8\xF2\x1C\xE7\xF9\xC6\x3B"
|
||||
"\x68\xB9\x72\x43\x86\xEF\xA9\x94\x68\x02\xEF\x7D\x77\xE0\x0A\xD1\xD7\x48\xFD\xCD"
|
||||
"\x98\xDA\x13\x8A\x76\x48\xD4\x0F\x63\x28\xFA\x01\x1B\xF3\xC7\x15\xB8\x53\x22\x7E"
|
||||
"\x77\x29\x28\x31\x3A\x75\x36\x35\x3A\x00\xB3\xBB\x4D\xEE\x5A\xAF\xD0\xF2\x56\x8A"
|
||||
"\x10\x2D\x6F\x4B\x2D\x76\x49\x9B\xE9\xA8\x60\x5D\x9E\x7E\x50\x86\xF1\xA1\x0F\x28"
|
||||
"\x9B\x7B\xE8\xDD\x1F\x87\x4E\x79\x7B\x50\x12\xA7\xB4\x8B\x52\x38\xEC\x7C\xBB\xB9"
|
||||
"\x55\x87\x11\x1C\x74\xE7\x7F\xA0\xBA\xE3\x34\x5D\x61\xBF\x29\x29\x29\x00"
|
||||
};
|
||||
|
||||
struct
|
||||
{
|
||||
const char *key;
|
||||
const char *passphrase;
|
||||
int no_result_expected;
|
||||
int compare_results;
|
||||
unsigned char *result_expected;
|
||||
size_t resultlen_expected;
|
||||
int ret_expected;
|
||||
unsigned char *result;
|
||||
size_t resultlen;
|
||||
} specs[] =
|
||||
{
|
||||
/* Invalid S-Expressions */
|
||||
/* - non-NULL */
|
||||
{ "",
|
||||
"passphrase", 1, 0, NULL, 0, GPG_ERR_INV_SEXP, NULL, 0 },
|
||||
/* - NULL; disabled, this segfaults */
|
||||
//{ NULL,
|
||||
// "passphrase", 1, NULL, 0, GPG_ERR_INV_SEXP, NULL, 0 },
|
||||
|
||||
/* Valid and invalid keys. */
|
||||
{ key_rsa_valid.string,
|
||||
"passphrase", 0, 0, NULL, 0, 0, NULL, 0 },
|
||||
{ key_rsa_bogus_0.string,
|
||||
"passphrase", 0, 0, NULL, 0, GPG_ERR_INV_SEXP, NULL, 0 },
|
||||
{ key_rsa_bogus_1.string,
|
||||
"passphrase", 0, 0, NULL, 0, GPG_ERR_INV_SEXP, NULL, 0 },
|
||||
|
||||
/* FIXME: add more test data. */
|
||||
};
|
||||
|
||||
for (i = 0; i < DIM (specs); i++)
|
||||
{
|
||||
ret = agent_protect ((const unsigned char*)specs[i].key,
|
||||
specs[i].passphrase,
|
||||
&specs[i].result, &specs[i].resultlen);
|
||||
if (gpg_err_code (ret) != specs[i].ret_expected)
|
||||
{
|
||||
printf ("agent_protect() returned `%i/%s'; expected `%i/%s'\n",
|
||||
ret, gpg_strerror (ret),
|
||||
specs[i].ret_expected, gpg_strerror (specs[i].ret_expected));
|
||||
abort ();
|
||||
}
|
||||
|
||||
if (specs[i].no_result_expected)
|
||||
{
|
||||
assert (! specs[i].result);
|
||||
assert (! specs[i].resultlen);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (specs[i].compare_results)
|
||||
{
|
||||
assert (specs[i].resultlen == specs[i].resultlen_expected);
|
||||
if (specs[i].result_expected)
|
||||
assert (! memcmp (specs[i].result, specs[i].result_expected,
|
||||
specs[i].resultlen));
|
||||
else
|
||||
assert (! specs[i].result);
|
||||
}
|
||||
xfree (specs[i].result);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
test_agent_unprotect (void)
|
||||
{
|
||||
/* Unprotect the key encoded in canonical format. We assume a valid
|
||||
S-Exp here. */
|
||||
/* int */
|
||||
/* agent_unprotect (const unsigned char *protectedkey, const char *passphrase, */
|
||||
/* unsigned char **result, size_t *resultlen) */
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
test_agent_private_key_type (void)
|
||||
{
|
||||
/* Check the type of the private key, this is one of the constants:
|
||||
PRIVATE_KEY_UNKNOWN if we can't figure out the type (this is the
|
||||
value 0), PRIVATE_KEY_CLEAR for an unprotected private key.
|
||||
PRIVATE_KEY_PROTECTED for an protected private key or
|
||||
PRIVATE_KEY_SHADOWED for a sub key where the secret parts are stored
|
||||
elsewhere. */
|
||||
/* int */
|
||||
/* agent_private_key_type (const unsigned char *privatekey) */
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
test_make_shadow_info (void)
|
||||
{
|
||||
#if 0
|
||||
static struct
|
||||
{
|
||||
const char *snstr;
|
||||
const char *idstr;
|
||||
const char *expected;
|
||||
} data[] = {
|
||||
{ "", "", NULL },
|
||||
|
||||
};
|
||||
int i;
|
||||
unsigned char *result;
|
||||
|
||||
for (i=0; i < DIM(data); i++)
|
||||
{
|
||||
result = make_shadow_info (data[i].snstr, data[i].idstr);
|
||||
if (!result && !data[i].expected)
|
||||
pass ();
|
||||
else if (!result && data[i].expected)
|
||||
fail ();
|
||||
else if (!data[i].expected)
|
||||
fail ();
|
||||
/* fixme: Need to compare the result but also need to check
|
||||
proper S-expression syntax. */
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void
|
||||
test_agent_shadow_key (void)
|
||||
{
|
||||
/* Create a shadow key from a public key. We use the shadow protocol
|
||||
"ti-v1" and insert the S-expressionn SHADOW_INFO. The resulting
|
||||
S-expression is returned in an allocated buffer RESULT will point
|
||||
to. The input parameters are expected to be valid canonicalized
|
||||
S-expressions */
|
||||
/* int */
|
||||
/* agent_shadow_key (const unsigned char *pubkey, */
|
||||
/* const unsigned char *shadow_info, */
|
||||
/* unsigned char **result) */
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
test_agent_get_shadow_info (void)
|
||||
{
|
||||
/* Parse a canonical encoded shadowed key and return a pointer to the
|
||||
inner list with the shadow_info */
|
||||
/* int */
|
||||
/* agent_get_shadow_info (const unsigned char *shadowkey, */
|
||||
/* unsigned char const **shadow_info) */
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
gcry_control (GCRYCTL_DISABLE_SECMEM);
|
||||
|
||||
test_agent_protect ();
|
||||
test_agent_unprotect ();
|
||||
test_agent_private_key_type ();
|
||||
test_make_shadow_info ();
|
||||
test_agent_shadow_key ();
|
||||
test_agent_get_shadow_info ();
|
||||
|
||||
return 0;
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
/* memrchr.c - libc replacement function
|
||||
* Copyright (C) 2005 Free Software Foundation, Inc.
|
||||
/* trans.c - translatable strings
|
||||
* Copyright (C) 2001 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of GnuPG.
|
||||
*
|
||||
@ -19,31 +19,25 @@
|
||||
* USA.
|
||||
*/
|
||||
|
||||
/*
|
||||
memrchr() is a GNU function that might not be available everywhere.
|
||||
It's basically the inverse of memchr() - search backwards in a
|
||||
memory block for a particular character.
|
||||
*/
|
||||
/* To avoid any problems with the gettext implementation (there used
|
||||
to be some vulnerabilities in the last years and the use of
|
||||
external files is a minor security problem in itself), we use our
|
||||
own simple translation stuff */
|
||||
|
||||
#include <config.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <assert.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
/* There are many ways to optimize this, but this is a simple
|
||||
unoptimized implementation. */
|
||||
void *
|
||||
memrchr(const void *s, int c, size_t n)
|
||||
#include "agent.h"
|
||||
|
||||
const char *
|
||||
trans (const char *text)
|
||||
{
|
||||
const unsigned char *start=s,*end=s;
|
||||
|
||||
end+=n-1;
|
||||
|
||||
while(end>=start)
|
||||
{
|
||||
if(*end==c)
|
||||
return (void *)end;
|
||||
else
|
||||
end--;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
return text;
|
||||
}
|
418
agent/trustlist.c
Normal file
@ -0,0 +1,418 @@
|
||||
/* trustlist.c - Maintain the list of trusted keys
|
||||
* Copyright (C) 2002, 2004 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of GnuPG.
|
||||
*
|
||||
* GnuPG is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* GnuPG is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
|
||||
* USA.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <assert.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include "agent.h"
|
||||
#include <assuan.h> /* fixme: need a way to avoid assuan calls here */
|
||||
#include "i18n.h"
|
||||
|
||||
static const char headerblurb[] =
|
||||
"# This is the list of trusted keys. Comment lines, like this one, as\n"
|
||||
"# well as empty lines are ignored. The entire file may be integrity\n"
|
||||
"# protected by the use of a MAC, so changing the file does not make\n"
|
||||
"# sense without the knowledge of the MAC key. Lines do have a length\n"
|
||||
"# limit but this is not serious limitation as the format of the\n"
|
||||
"# entries is fixed and checked by gpg-agent: A non-comment line starts\n"
|
||||
"# with optional white spaces, followed by the SHA-1 fingerpint in hex,\n"
|
||||
"# optionally followed by a flag character which my either be 'P', 'S'\n"
|
||||
"# or '*'. Additional data, delimited by white space, is ignored.\n"
|
||||
"#\n"
|
||||
"# NOTE: You should give the gpg-agent a HUP after editing this file.\n"
|
||||
"\n";
|
||||
|
||||
|
||||
static FILE *trustfp;
|
||||
static int trustfp_used; /* Counter to track usage of TRUSTFP. */
|
||||
static int reload_trustlist_pending;
|
||||
|
||||
|
||||
static int
|
||||
open_list (int append)
|
||||
{
|
||||
char *fname;
|
||||
|
||||
fname = make_filename (opt.homedir, "trustlist.txt", NULL);
|
||||
trustfp = fopen (fname, append? "a+":"r");
|
||||
if (!trustfp && errno == ENOENT)
|
||||
{
|
||||
trustfp = fopen (fname, "wx");
|
||||
if (!trustfp)
|
||||
{
|
||||
gpg_error_t tmperr = gpg_error (gpg_err_code_from_errno (errno));
|
||||
log_error ("can't create `%s': %s\n", fname, strerror (errno));
|
||||
xfree (fname);
|
||||
return tmperr;
|
||||
}
|
||||
fputs (headerblurb, trustfp);
|
||||
fclose (trustfp);
|
||||
trustfp = fopen (fname, append? "a+":"r");
|
||||
}
|
||||
|
||||
if (!trustfp)
|
||||
{
|
||||
gpg_error_t tmperr = gpg_error (gpg_err_code_from_errno (errno));
|
||||
log_error ("can't open `%s': %s\n", fname, strerror (errno));
|
||||
xfree (fname);
|
||||
return tmperr;
|
||||
}
|
||||
|
||||
/*FIXME: check the MAC */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Read the trustlist and return entry by entry. KEY must point to a
|
||||
buffer of at least 41 characters. KEYFLAG does return either 'P',
|
||||
'S' or '*'.
|
||||
|
||||
Reading a valid entry return 0, EOF returns -1 any other error
|
||||
returns the appropriate error code. */
|
||||
static int
|
||||
read_list (char *key, int *keyflag)
|
||||
{
|
||||
int rc;
|
||||
int c, i, j;
|
||||
char *p, line[256];
|
||||
|
||||
if (!trustfp)
|
||||
{
|
||||
rc = open_list (0);
|
||||
if (rc)
|
||||
return rc;
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
if (!fgets (line, DIM(line)-1, trustfp) )
|
||||
{
|
||||
if (feof (trustfp))
|
||||
return -1;
|
||||
return gpg_error (gpg_err_code_from_errno (errno));
|
||||
}
|
||||
|
||||
if (!*line || line[strlen(line)-1] != '\n')
|
||||
{
|
||||
/* eat until end of line */
|
||||
while ( (c=getc (trustfp)) != EOF && c != '\n')
|
||||
;
|
||||
return gpg_error (*line? GPG_ERR_LINE_TOO_LONG
|
||||
: GPG_ERR_INCOMPLETE_LINE);
|
||||
}
|
||||
|
||||
/* Allow for empty lines and spaces */
|
||||
for (p=line; spacep (p); p++)
|
||||
;
|
||||
}
|
||||
while (!*p || *p == '\n' || *p == '#');
|
||||
|
||||
for (i=j=0; (p[i] == ':' || hexdigitp (p+i)) && j < 40; i++)
|
||||
if ( p[i] != ':' )
|
||||
key[j++] = p[i] >= 'a'? (p[i] & 0xdf): p[i];
|
||||
key[j] = 0;
|
||||
if (j!=40 || !(spacep (p+i) || p[i] == '\n'))
|
||||
{
|
||||
log_error ("invalid formatted fingerprint in trustlist\n");
|
||||
return gpg_error (GPG_ERR_BAD_DATA);
|
||||
}
|
||||
assert (p[i]);
|
||||
if (p[i] == '\n')
|
||||
*keyflag = '*';
|
||||
else
|
||||
{
|
||||
i++;
|
||||
if ( p[i] == 'P' || p[i] == 'p')
|
||||
*keyflag = 'P';
|
||||
else if ( p[i] == 'S' || p[i] == 's')
|
||||
*keyflag = 'S';
|
||||
else if ( p[i] == '*')
|
||||
*keyflag = '*';
|
||||
else
|
||||
{
|
||||
log_error ("invalid keyflag in trustlist\n");
|
||||
return gpg_error (GPG_ERR_BAD_DATA);
|
||||
}
|
||||
i++;
|
||||
if ( !(spacep (p+i) || p[i] == '\n'))
|
||||
{
|
||||
log_error ("invalid keyflag in trustlist\n");
|
||||
return gpg_error (GPG_ERR_BAD_DATA);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Check whether the given fpr is in our trustdb. We expect FPR to be
|
||||
an all uppercase hexstring of 40 characters. */
|
||||
int
|
||||
agent_istrusted (const char *fpr)
|
||||
{
|
||||
int rc;
|
||||
static char key[41];
|
||||
int keyflag;
|
||||
|
||||
trustfp_used++;
|
||||
if (trustfp)
|
||||
rewind (trustfp);
|
||||
while (!(rc=read_list (key, &keyflag)))
|
||||
{
|
||||
if (!strcmp (key, fpr))
|
||||
{
|
||||
trustfp_used--;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
if (rc != -1)
|
||||
{
|
||||
/* Error in the trustdb - close it to give the user a chance for
|
||||
correction */
|
||||
if (trustfp)
|
||||
fclose (trustfp);
|
||||
trustfp = NULL;
|
||||
}
|
||||
trustfp_used--;
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
/* Write all trust entries to FP. */
|
||||
int
|
||||
agent_listtrusted (void *assuan_context)
|
||||
{
|
||||
int rc;
|
||||
static char key[51];
|
||||
int keyflag;
|
||||
|
||||
trustfp_used++;
|
||||
if (trustfp)
|
||||
rewind (trustfp);
|
||||
while (!(rc=read_list (key, &keyflag)))
|
||||
{
|
||||
key[40] = ' ';
|
||||
key[41] = keyflag;
|
||||
key[42] = '\n';
|
||||
assuan_send_data (assuan_context, key, 43);
|
||||
assuan_send_data (assuan_context, NULL, 0); /* flush */
|
||||
}
|
||||
if (rc == -1)
|
||||
rc = 0;
|
||||
if (rc)
|
||||
{
|
||||
/* Error in the trustdb - close it to give the user a chance for
|
||||
correction */
|
||||
if (trustfp)
|
||||
fclose (trustfp);
|
||||
trustfp = NULL;
|
||||
}
|
||||
trustfp_used--;
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
/* Insert the given fpr into our trustdb. We expect FPR to be an all
|
||||
uppercase hexstring of 40 characters. FLAG is either 'P' or 'C'.
|
||||
This function does first check whether that key has alreay been put
|
||||
into the trustdb and returns success in this case. Before a FPR
|
||||
actually gets inserted, the user is asked by means of the pin-entry
|
||||
whether this is actual wants he want to do.
|
||||
*/
|
||||
int
|
||||
agent_marktrusted (CTRL ctrl, const char *name, const char *fpr, int flag)
|
||||
{
|
||||
int rc;
|
||||
static char key[41];
|
||||
int keyflag;
|
||||
char *desc;
|
||||
char *fname;
|
||||
|
||||
/* Check whether we are at all allowed to modify the trustlist.
|
||||
This is useful so that the trustlist may be a symlink to a global
|
||||
trustlist with only admin priviliges to modify it. Of course
|
||||
this is not a secure way of denying access, but it avoids the
|
||||
usual clicking on an Okay buttun thing most users are used to. */
|
||||
fname = make_filename (opt.homedir, "trustlist.txt", NULL);
|
||||
rc = access (fname, W_OK);
|
||||
if (rc && errno != ENOENT)
|
||||
{
|
||||
xfree (fname);
|
||||
return gpg_error (GPG_ERR_EPERM);
|
||||
}
|
||||
xfree (fname);
|
||||
|
||||
trustfp_used++;
|
||||
if (trustfp)
|
||||
rewind (trustfp);
|
||||
while (!(rc=read_list (key, &keyflag)))
|
||||
{
|
||||
if (!strcmp (key, fpr))
|
||||
return 0;
|
||||
}
|
||||
if (trustfp)
|
||||
fclose (trustfp);
|
||||
trustfp = NULL;
|
||||
if (rc != -1)
|
||||
{
|
||||
trustfp_used--;
|
||||
return rc; /* Error in the trustlist. */
|
||||
}
|
||||
|
||||
/* This feature must explicitly been enabled. */
|
||||
if (!opt.allow_mark_trusted)
|
||||
{
|
||||
trustfp_used--;
|
||||
return gpg_error (GPG_ERR_NOT_SUPPORTED);
|
||||
}
|
||||
|
||||
/* Insert a new one. */
|
||||
if (asprintf (&desc,
|
||||
/* TRANSLATORS: This prompt is shown by the Pinentry
|
||||
and has one special property: A "%%0A" is used by
|
||||
Pinentry to insert a line break. The double
|
||||
percent sign is actually needed because it is also
|
||||
a printf format string. If you need to insert a
|
||||
plain % sign, you need to encode it as "%%25". The
|
||||
second "%s" gets replaced by a hexdecimal
|
||||
fingerprint string whereas the first one receives
|
||||
the name as store in the certificate. */
|
||||
_("Please verify that the certificate identified as:%%0A"
|
||||
" \"%s\"%%0A"
|
||||
"has the fingerprint:%%0A"
|
||||
" %s"), name, fpr) < 0 )
|
||||
{
|
||||
trustfp_used--;
|
||||
return out_of_core ();
|
||||
}
|
||||
|
||||
/* TRANSLATORS: "Correct" is the label of a button and intended to
|
||||
be hit if the fingerprint matches the one of the CA. The other
|
||||
button is "the default "Cancel" of the Pinentry. */
|
||||
rc = agent_get_confirmation (ctrl, desc, _("Correct"), NULL);
|
||||
free (desc);
|
||||
if (rc)
|
||||
{
|
||||
trustfp_used--;
|
||||
return rc;
|
||||
}
|
||||
|
||||
if (asprintf (&desc,
|
||||
/* TRANSLATORS: This prompt is shown by the Pinentry
|
||||
and has one special property: A "%%0A" is used by
|
||||
Pinentry to insert a line break. The double
|
||||
percent sign is actually needed because it is also
|
||||
a printf format string. If you need to insert a
|
||||
plain % sign, you need to encode it as "%%25". The
|
||||
"%s" gets replaced by the name as store in the
|
||||
certificate. */
|
||||
_("Do you ultimately trust%%0A"
|
||||
" \"%s\"%%0A"
|
||||
"to correctly certify user certificates?"),
|
||||
name) < 0 )
|
||||
{
|
||||
trustfp_used--;
|
||||
return out_of_core ();
|
||||
}
|
||||
rc = agent_get_confirmation (ctrl, desc, _("Yes"), _("No"));
|
||||
free (desc);
|
||||
if (rc)
|
||||
{
|
||||
trustfp_used--;
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* Now check again to avoid duplicates. Also open in append mode now. */
|
||||
rc = open_list (1);
|
||||
if (rc)
|
||||
{
|
||||
trustfp_used--;
|
||||
return rc;
|
||||
}
|
||||
rewind (trustfp);
|
||||
while (!(rc=read_list (key, &keyflag)))
|
||||
{
|
||||
if (!strcmp (key, fpr))
|
||||
{
|
||||
trustfp_used--;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
if (rc != -1)
|
||||
{
|
||||
if (trustfp)
|
||||
fclose (trustfp);
|
||||
trustfp = NULL;
|
||||
trustfp_used--;
|
||||
return rc; /* Error in the trustlist. */
|
||||
}
|
||||
rc = 0;
|
||||
|
||||
/* Append the key. */
|
||||
fflush (trustfp);
|
||||
fputs ("\n# ", trustfp);
|
||||
print_sanitized_string (trustfp, name, 0);
|
||||
fprintf (trustfp, "\n%s %c\n", fpr, flag);
|
||||
if (ferror (trustfp))
|
||||
rc = gpg_error (gpg_err_code_from_errno (errno));
|
||||
|
||||
/* close because we are in append mode */
|
||||
if (fclose (trustfp))
|
||||
rc = gpg_error (gpg_err_code_from_errno (errno));
|
||||
trustfp = NULL;
|
||||
trustfp_used--;
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
agent_trustlist_housekeeping (void)
|
||||
{
|
||||
if (reload_trustlist_pending && !trustfp_used)
|
||||
{
|
||||
if (trustfp)
|
||||
{
|
||||
fclose (trustfp);
|
||||
trustfp = NULL;
|
||||
}
|
||||
reload_trustlist_pending = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Not all editors are editing files in place, thus a changes
|
||||
trustlist.txt won't be recognozed if we keep the file descriptor
|
||||
open. This function may be used to explicitly close that file
|
||||
descriptor, which will force a reopen in turn. */
|
||||
void
|
||||
agent_reload_trustlist (void)
|
||||
{
|
||||
reload_trustlist_pending = 1;
|
||||
agent_trustlist_housekeeping ();
|
||||
}
|
47
am/cmacros.am
Normal file
@ -0,0 +1,47 @@
|
||||
# cmacros.am - C macro definitions
|
||||
# Copyright (C) 2004 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is part of GnuPG.
|
||||
#
|
||||
# GnuPG is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# GnuPG is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
|
||||
# USA.
|
||||
|
||||
localedir = $(datadir)/locale
|
||||
|
||||
AM_CPPFLAGS += -DLOCALEDIR=\"$(localedir)\"
|
||||
|
||||
if ! HAVE_DOSISH_SYSTEM
|
||||
AM_CPPFLAGS += -DGNUPG_BINDIR="\"$(bindir)\"" \
|
||||
-DGNUPG_LIBEXECDIR="\"$(libexecdir)\"" \
|
||||
-DGNUPG_LIBDIR="\"$(libdir)/@PACKAGE@\"" \
|
||||
-DGNUPG_DATADIR="\"$(datadir)/@PACKAGE@\"" \
|
||||
-DGNUPG_SYSCONFDIR="\"$(sysconfdir)/@PACKAGE@\""
|
||||
endif
|
||||
|
||||
if GNUPG_AGENT_PGM
|
||||
AM_CPPFLAGS += -DGNUPG_DEFAULT_AGENT="\"@GNUPG_AGENT_PGM@\""
|
||||
endif
|
||||
if GNUPG_PINENTRY_PGM
|
||||
AM_CPPFLAGS += -DGNUPG_DEFAULT_PINENTRY="\"@GNUPG_PINENTRY_PGM@\""
|
||||
endif
|
||||
if GNUPG_SCDAEMON_PGM
|
||||
AM_CPPFLAGS += -DGNUPG_DEFAULT_SCDAEMON="\"@GNUPG_SCDAEMON_PGM@\""
|
||||
endif
|
||||
if GNUPG_DIRMNGR_PGM
|
||||
AM_CPPFLAGS += -DGNUPG_DEFAULT_DIRMNGR="\"@GNUPG_DIRMNGR_PGM@\""
|
||||
endif
|
||||
if GNUPG_PROTECT_TOOL_PGM
|
||||
AM_CPPFLAGS += -DGNUPG_DEFAULT_PROTECT_TOOL="\"@GNUPG_PROTECT_TOOL_PGM@\""
|
||||
endif
|
2
artwork/README
Normal file
@ -0,0 +1,2 @@
|
||||
These is a collection of graphics used in connection with GnuPG. It
|
||||
is not part of GnuPG proper. [wk 2004-09-11]
|
5
artwork/ascii-key
Normal file
@ -0,0 +1,5 @@
|
||||
|
||||
.-.
|
||||
( )====GnuPG
|
||||
`-'
|
||||
|
BIN
artwork/gnu-head-sm.jpg
Normal file
After Width: | Height: | Size: 5.9 KiB |
BIN
artwork/gnu1.jpg
Normal file
After Width: | Height: | Size: 20 KiB |
BIN
artwork/gnu5.png
Normal file
After Width: | Height: | Size: 5.3 KiB |
BIN
artwork/gnud.png
Normal file
After Width: | Height: | Size: 5.6 KiB |
BIN
artwork/gnue.png
Normal file
After Width: | Height: | Size: 6.1 KiB |
BIN
artwork/gnue2.png
Normal file
After Width: | Height: | Size: 5.8 KiB |
BIN
artwork/gnupg-1.0-available-now.png
Normal file
After Width: | Height: | Size: 4.4 KiB |
BIN
artwork/gnupg-1.0-ist-da.png
Normal file
After Width: | Height: | Size: 4.2 KiB |
BIN
artwork/gnupg-badge-openpgp.cdr.gz
Normal file
BIN
artwork/gnupg-badge-openpgp.eps.gz
Normal file
BIN
artwork/gnupg-badge-openpgp.jpg
Normal file
After Width: | Height: | Size: 62 KiB |
BIN
artwork/gnupg-logo-black.jpg
Normal file
After Width: | Height: | Size: 38 KiB |
BIN
artwork/gnupg-logo-cia.jpg
Normal file
After Width: | Height: | Size: 23 KiB |
BIN
artwork/gnupg-logo-cia2.jpg
Normal file
After Width: | Height: | Size: 62 KiB |
BIN
artwork/gnurieg.png
Normal file
After Width: | Height: | Size: 1.7 KiB |
BIN
artwork/gpglogo.eps.gz
Normal file
36
artwork/gpglogo.fig
Normal file
@ -0,0 +1,36 @@
|
||||
#FIG 3.2
|
||||
Landscape
|
||||
Center
|
||||
Metric
|
||||
A4
|
||||
100.00
|
||||
Single
|
||||
-2
|
||||
1200 2
|
||||
0 32 #414541
|
||||
0 33 #8e8e8e
|
||||
0 34 #414541
|
||||
0 35 #8e8e8e
|
||||
0 36 #8e8e8e
|
||||
6 91 46 7785 7740
|
||||
1 3 0 2 0 7 100 0 -1 0.000 1 0.0000 3938 3893 3832 3832 3938 3893 7763 4118
|
||||
1 3 0 2 0 7 100 0 -1 0.000 1 0.0000 3938 3893 2959 2959 3938 3893 6863 4343
|
||||
2 5 0 1 0 -1 100 0 -1 0.000 0 0 -1 0 0 5
|
||||
0 tmp/gnu1.jpg
|
||||
1628 2303 6248 2303 6248 5633 1628 5633 1628 2303
|
||||
4 0 0 100 0 30 40 0.0000 4 450 480 3713 743 N\001
|
||||
4 0 0 100 0 30 40 0.2618 4 450 465 2918 908 G\001
|
||||
4 0 0 100 0 30 40 6.0214 4 450 450 4527 791 U\001
|
||||
4 0 0 100 0 30 40 6.0214 4 330 330 3046 7398 c\001
|
||||
4 0 0 100 0 30 40 0.8727 4 330 285 6684 6299 r\001
|
||||
4 0 0 100 0 30 40 0.0000 4 465 390 3668 7493 y\001
|
||||
4 0 0 100 0 30 40 5.9341 4 330 345 2488 7193 a\001
|
||||
4 0 0 100 0 30 40 5.7596 4 330 390 1944 6889 v\001
|
||||
4 0 0 100 0 30 40 5.4978 4 465 195 1562 6609 i\001
|
||||
4 0 0 100 0 30 40 5.4105 4 330 285 1198 6206 r\001
|
||||
4 0 0 100 0 30 40 5.3233 4 450 375 826 5724 P\001
|
||||
4 0 0 100 0 30 40 0.5236 4 330 390 5681 7140 u\001
|
||||
4 0 0 100 0 30 40 0.6981 4 330 345 6247 6739 a\001
|
||||
4 0 0 100 0 30 40 1.0472 4 465 390 7039 5909 d\001
|
||||
4 0 0 100 0 30 40 0.3491 4 450 465 5031 7399 G\001
|
||||
-6
|
BIN
artwork/gpglogo.jpg
Normal file
After Width: | Height: | Size: 3.9 KiB |
BIN
artwork/tl-gnu1.jpg
Normal file
After Width: | Height: | Size: 4.8 KiB |
165
autogen.sh
@ -1,5 +1,164 @@
|
||||
#!/bin/sh
|
||||
#! /bin/sh
|
||||
# Run this to generate all the initial makefiles, etc.
|
||||
#
|
||||
# Copyright (C) 2003 g10 Code GmbH
|
||||
#
|
||||
# This file is free software; as a special exception the author gives
|
||||
# unlimited permission to copy and/or distribute it, with or without
|
||||
# modifications, as long as this notice is preserved.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful, but
|
||||
# WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
|
||||
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
autogen_sh="`dirname $0`/scripts/autogen.sh"
|
||||
exec $autogen_sh $*
|
||||
configure_ac="configure.ac"
|
||||
|
||||
cvtver () {
|
||||
awk 'NR==1 {split($NF,A,".");X=1000000*A[1]+1000*A[2]+A[3];print X;exit 0}'
|
||||
}
|
||||
|
||||
check_version () {
|
||||
if [ `("$1" --version || echo "0") | cvtver` -ge "$2" ]; then
|
||||
return 0
|
||||
fi
|
||||
echo "**Error**: "\`$1\'" not installed or too old." >&2
|
||||
echo ' Version '$3' or newer is required.' >&2
|
||||
[ -n "$4" ] && echo ' Note that this is part of '\`$4\''.' >&2
|
||||
DIE="yes"
|
||||
return 1
|
||||
}
|
||||
|
||||
# Allow to override the default tool names
|
||||
AUTOCONF=${AUTOCONF_PREFIX}${AUTOCONF:-autoconf}${AUTOCONF_SUFFIX}
|
||||
AUTOHEADER=${AUTOCONF_PREFIX}${AUTOHEADER:-autoheader}${AUTOCONF_SUFFIX}
|
||||
|
||||
AUTOMAKE=${AUTOMAKE_PREFIX}${AUTOMAKE:-automake}${AUTOMAKE_SUFFIX}
|
||||
ACLOCAL=${AUTOMAKE_PREFIX}${ACLOCAL:-aclocal}${AUTOMAKE_SUFFIX}
|
||||
|
||||
GETTEXT=${GETTEXT_PREFIX}${GETTEXT:-gettext}${GETTEXT_SUFFIX}
|
||||
MSGMERGE=${GETTEXT_PREFIX}${MSGMERGE:-msgmerge}${GETTEXT_SUFFIX}
|
||||
|
||||
DIE=no
|
||||
|
||||
# ***** W32 build script *******
|
||||
# Used to cross-compile for Windows.
|
||||
if test "$1" = "--build-w32"; then
|
||||
tmp=`dirname $0`
|
||||
tsdir=`cd "$tmp"; pwd`
|
||||
shift
|
||||
if [ ! -f $tsdir/scripts/config.guess ]; then
|
||||
echo "$tsdir/scripts/config.guess not found" >&2
|
||||
exit 1
|
||||
fi
|
||||
build=`$tsdir/scripts/config.guess`
|
||||
|
||||
[ -z "$w32root" ] && w32root="$HOME/w32root"
|
||||
echo "Using $w32root as standard install directory" >&2
|
||||
|
||||
# See whether we have the Debian cross compiler package or the
|
||||
# old mingw32/cpd system
|
||||
if i586-mingw32msvc-gcc --version >/dev/null 2>&1 ; then
|
||||
host=i586-mingw32msvc
|
||||
crossbindir=/usr/$host/bin
|
||||
else
|
||||
host=i386--mingw32
|
||||
if ! mingw32 --version >/dev/null; then
|
||||
echo "We need at least version 0.3 of MingW32/CPD" >&2
|
||||
exit 1
|
||||
fi
|
||||
crossbindir=`mingw32 --install-dir`/bin
|
||||
# Old autoconf version required us to setup the environment
|
||||
# with the proper tool names.
|
||||
CC=`mingw32 --get-path gcc`
|
||||
CPP=`mingw32 --get-path cpp`
|
||||
AR=`mingw32 --get-path ar`
|
||||
RANLIB=`mingw32 --get-path ranlib`
|
||||
export CC CPP AR RANLIB
|
||||
fi
|
||||
|
||||
if [ -f "$tsdir/config.log" ]; then
|
||||
if ! head $tsdir/config.log | grep "$host" >/dev/null; then
|
||||
echo "Pease run a 'make distclean' first" >&2
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
./configure --enable-maintainer-mode --prefix=${w32root} \
|
||||
--host=i586-mingw32msvc --build=${build} \
|
||||
--with-gpg-error-prefix=${w32root} \
|
||||
--with-ksba-prefix=${w32root} \
|
||||
--with-libgcrypt-prefix=${w32root} \
|
||||
--with-libassuan-prefix=${w32root} \
|
||||
--with-zlib=${w32root} \
|
||||
--with-pth-prefix=${w32root} \
|
||||
--disable-gpg
|
||||
rc=$?
|
||||
# Ugly hack to overcome a gettext problem. Someone should look into
|
||||
# gettext to figure out why the po directory is not ignored as it used
|
||||
# to be.
|
||||
[ $rc = 0 ] && touch $tsdir/po/all
|
||||
exit $rc
|
||||
fi
|
||||
# ***** end W32 build script *******
|
||||
|
||||
|
||||
|
||||
|
||||
# Grep the required versions from configure.ac
|
||||
autoconf_vers=`sed -n '/^AC_PREREQ(/ {
|
||||
s/^.*(\(.*\))/\1/p
|
||||
q
|
||||
}' ${configure_ac}`
|
||||
autoconf_vers_num=`echo "$autoconf_vers" | cvtver`
|
||||
|
||||
automake_vers=`sed -n '/^min_automake_version=/ {
|
||||
s/^.*="\(.*\)"/\1/p
|
||||
q
|
||||
}' ${configure_ac}`
|
||||
automake_vers_num=`echo "$automake_vers" | cvtver`
|
||||
|
||||
gettext_vers=`sed -n '/^AM_GNU_GETTEXT_VERSION(/ {
|
||||
s/^.*(\(.*\))/\1/p
|
||||
q
|
||||
}' ${configure_ac}`
|
||||
gettext_vers_num=`echo "$gettext_vers" | cvtver`
|
||||
|
||||
|
||||
if [ -z "$autoconf_vers" -o -z "$automake_vers" -o -z "$gettext_vers" ]
|
||||
then
|
||||
echo "**Error**: version information not found in "\`${configure_ac}\'"." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
|
||||
if check_version $AUTOCONF $autoconf_vers_num $autoconf_vers ; then
|
||||
check_version $AUTOHEADER $autoconf_vers_num $autoconf_vers autoconf
|
||||
fi
|
||||
if check_version $AUTOMAKE $automake_vers_num $automake_vers; then
|
||||
check_version $ACLOCAL $automake_vers_num $autoconf_vers automake
|
||||
fi
|
||||
if check_version $GETTEXT $gettext_vers_num $gettext_vers; then
|
||||
check_version $MSGMERGE $gettext_vers_num $gettext_vers gettext
|
||||
fi
|
||||
|
||||
if test "$DIE" = "yes"; then
|
||||
cat <<EOF
|
||||
|
||||
Note that you may use alternative versions of the tools by setting
|
||||
the corresponding environment variables; see README.CVS for details.
|
||||
|
||||
EOF
|
||||
exit 1
|
||||
fi
|
||||
|
||||
|
||||
echo "Running aclocal -I m4 -I gl/m4 ${ACLOCAL_FLAGS:+$ACLOCAL_FLAGS }..."
|
||||
$ACLOCAL -I m4 -I gl/m4 $ACLOCAL_FLAGS
|
||||
echo "Running autoheader..."
|
||||
$AUTOHEADER
|
||||
echo "Running automake --gnu ..."
|
||||
$AUTOMAKE --gnu;
|
||||
echo "Running autoconf..."
|
||||
$AUTOCONF
|
||||
|
||||
echo "You may now run \"./configure --enable-maintainer-mode && make\"."
|
||||
|
15
build-w32.sh
Normal file
@ -0,0 +1,15 @@
|
||||
#!/bin/sh
|
||||
|
||||
[ -z "$w32root" ] && w32root="$HOME/w32root"
|
||||
|
||||
./configure --enable-maintainer-mode --prefix=${w32root} \
|
||||
--host=i586-mingw32msvc --build=`scripts/config.guess` \
|
||||
--with-gpg-error-prefix=${w32root} \
|
||||
--with-ksba-prefix=${w32root} \
|
||||
--with-libgcrypt-prefix=${w32root} \
|
||||
--with-libassuan-prefix=${w32root} \
|
||||
--with-zlib=${w32root} \
|
||||
--with-pth-prefix=${w32root}
|
||||
|
||||
|
||||
|
272
checks/ChangeLog
@ -1,272 +0,0 @@
|
||||
2006-04-19 David Shaw <dshaw@jabberwocky.com>
|
||||
|
||||
* sigs.test, mds.test: Add tests for SHA-224, SHA-384, and
|
||||
SHA-512.
|
||||
|
||||
2006-04-11 Werner Koch <wk@g10code.com>
|
||||
|
||||
* armor.test: New.
|
||||
|
||||
2006-03-09 Werner Koch <wk@g10code.com>
|
||||
|
||||
* defs.inc: Removed Basishm by proper redirection.
|
||||
|
||||
2006-03-06 Werner Koch <wk@g10code.com>
|
||||
|
||||
* defs.inc: Print error messages also to stderr. Allow for
|
||||
verbose environment variable.
|
||||
(linefeed): New.
|
||||
(suspend_error, resume_error): New.
|
||||
* verify.test: More tests.
|
||||
* multisig.test: Better error printing.
|
||||
(sig_1ls1ls_valid, sig_ls_valid): Moved to the non-valid group.
|
||||
|
||||
2006-02-14 Werner Koch <wk@gnupg.org>
|
||||
|
||||
* verify.test: New.
|
||||
|
||||
2005-06-21 Werner Koch <wk@g10code.com>
|
||||
|
||||
* conventional.test (algos): Uhh ohh, cut+paste error and not
|
||||
tested.
|
||||
|
||||
2005-06-02 Werner Koch <wk@g10code.com>
|
||||
|
||||
* conventional.test: have_cipher_algo now requires uppercase
|
||||
algorithm names. Changed. Noted by John R. Shannon.
|
||||
|
||||
2004-02-09 David Shaw <dshaw@jabberwocky.com>
|
||||
|
||||
* clearsig.test, sigs.test: Properly detect RSA being missing, and
|
||||
use the proper key for doing an RSA test.
|
||||
|
||||
2003-12-31 David Shaw <dshaw@jabberwocky.com>
|
||||
|
||||
* clearsig.test, conventional-mdc.test, conventional.test,
|
||||
defs.inc, encrypt-dsa.test, encrypt.test, genkey1024.test,
|
||||
plain-1.asc, plain-1-pgp.asc, plain-2.asc, plain-3.asc,
|
||||
pubring.asc, secring.asc, sigs.test: Rework tests to work properly
|
||||
with a gpg binary that doesn't have all ciphers and all pk algos.
|
||||
Basically, we test for the ciphers we have, only test signing with
|
||||
non-160-bit hashes with RSA (we test all hashes as hashes). Test
|
||||
all key lengths of AES.
|
||||
|
||||
2003-12-05 David Shaw <dshaw@jabberwocky.com>
|
||||
|
||||
* Makefile.am: Reenable tests now that the Elgamal signature keys
|
||||
are gone.
|
||||
|
||||
* defs.inc, pubring.asc, secring.asc, plain-1.asc, plain-2.asc,
|
||||
plain-3.asc: Remove the old v3 Elgamal keys and replace with
|
||||
RSA+Elgamal and RSA s+e.
|
||||
|
||||
2003-12-03 David Shaw <dshaw@jabberwocky.com>
|
||||
|
||||
* options: Remove emulate-md-encode-bug.
|
||||
|
||||
2003-11-27 Werner Koch <wk@gnupg.org>
|
||||
|
||||
* Makefile.am (TESTS): Temporary remove tests using ElG signatures.
|
||||
|
||||
2003-09-04 David Shaw <dshaw@jabberwocky.com>
|
||||
|
||||
* mds.test, sigs.test: Remove TIGER/192 and make SHA-256 optional
|
||||
(since it might not be compiled in).
|
||||
|
||||
2003-07-10 David Shaw <dshaw@jabberwocky.com>
|
||||
|
||||
* Makefile.am: Add --no-permission-warning to avoid spurious
|
||||
warning when importing demo keys.
|
||||
|
||||
2003-05-27 Werner Koch <wk@gnupg.org>
|
||||
|
||||
* Makefile.am (CLEANFILES): Add gpg.conf
|
||||
|
||||
2003-05-26 David Shaw <dshaw@jabberwocky.com>
|
||||
|
||||
* defs.inc (pgmname): Make sure there is a valid options
|
||||
file. (From wk on stable branch)
|
||||
|
||||
* mds.test: Note that missing algorithms are not errors.
|
||||
|
||||
2003-04-23 David Shaw <dshaw@jabberwocky.com>
|
||||
|
||||
* Makefile.am, options.in: Rename options.in to options since it
|
||||
no longer needs to be a generated file.
|
||||
|
||||
* sigs.test: TODO note to add the new SHAs when we start
|
||||
generating them.
|
||||
|
||||
* mds.test: Test the new SHAs.
|
||||
|
||||
2002-05-10 Werner Koch <wk@gnupg.org>
|
||||
|
||||
* Makefile.am: Add gpg_dearmor to all targets where it is used.
|
||||
Noted by Andreas Haumer.
|
||||
|
||||
2002-04-19 Werner Koch <wk@gnupg.org>
|
||||
|
||||
* signencrypt-dsa.test, sigs-dsa.test: Don't check with MD5 as
|
||||
this is not valid with DSA signatures.
|
||||
|
||||
2001-12-22 Werner Koch <wk@gnupg.org>
|
||||
|
||||
* options.in: Add no-permission-warning.
|
||||
|
||||
2001-12-21 Werner Koch <wk@gnupg.org>
|
||||
|
||||
* Makefile.am (distclean-local): prefix mkdemodirs with srcdir
|
||||
(DISTCLEANFILES): Add random_seed.
|
||||
|
||||
2001-12-19 Werner Koch <wk@gnupg.org>
|
||||
|
||||
* options.in: Remove load-extension tiger
|
||||
* Makefile.am (./options): append it if there is such a module.
|
||||
|
||||
2001-10-23 Werner Koch <wk@gnupg.org>
|
||||
|
||||
* defs.inc, Makefile.am: Do not use $srcdir when invoking gpg.
|
||||
Write the logfile to the current directory.
|
||||
|
||||
2001-09-28 Werner Koch <wk@gnupg.org>
|
||||
|
||||
* defs.inc: Write a log file for each test.
|
||||
* run-gpg, run-gpgm, run-gpg.patterns: Removed. Replaced in all
|
||||
tests by a simple macro from defs.inc.
|
||||
* Makefile.am (CLEANFILES): Remove log files.
|
||||
(./gpg_dearmor): create it and use it instead of the macro.
|
||||
This is needed in multisig.test due to IFS tricks.
|
||||
|
||||
* armsignencrypt.test, signencrypt-dsa.test, signencrypt.test,
|
||||
armencryptp.test, armencrypt.test, encryptp.test, seat.test,
|
||||
encrypt-dsa.test, encrypt.test: Use --always-trust because the
|
||||
test are not designed to check the validity.
|
||||
|
||||
2001-09-06 Werner Koch <wk@gnupg.org>
|
||||
|
||||
* genkey1024.test: Simplified by using a parameter file.
|
||||
|
||||
2001-05-30 Werner Koch <wk@gnupg.org>
|
||||
|
||||
* multisig.test (IFS): Reset IFS just before the test.
|
||||
|
||||
2001-04-30 Werner Koch <wk@gnupg.org>
|
||||
|
||||
* multisig.test: Add an set +x to avoid ksh problems
|
||||
|
||||
2001-04-28 Werner Koch <wk@gnupg.org>
|
||||
|
||||
* run-gpg.patterns: a v3 test key expired yesterday, suppress the
|
||||
messages.
|
||||
|
||||
2001-03-27 Werner Koch <wk@gnupg.org>
|
||||
|
||||
* defs.inc: Removed creation of options file.
|
||||
* options.in: New.
|
||||
* Makefile.am: Create options file and fixed import of pubdemo.asc.
|
||||
|
||||
* run-gpg.patterns (gpg): Add some more patterns.
|
||||
|
||||
2001-03-20 Werner Koch <wk@gnupg.org>
|
||||
|
||||
* Makefile.am: Import the pubdemo.asc file
|
||||
|
||||
* sigs.test (hash_algo_list): s/tiger/tiger192/
|
||||
|
||||
2001-03-19 Werner Koch <wk@gnupg.org>
|
||||
|
||||
* mkdemodirs (GPGDEMO): Add --allow-secret-key-import to all gpg
|
||||
invocations. Use echon -n instead of an argument with \c.
|
||||
|
||||
2001-02-12 Werner Koch <wk@gnupg.org>
|
||||
|
||||
* multisig.test: new
|
||||
* Makefile.am (TESTS): Added.
|
||||
|
||||
2000-10-18 Werner Koch <wk@gnupg.org>
|
||||
|
||||
* conventional-mdc.test: Add Rijndael and fix for empty plain texts.
|
||||
|
||||
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>
|
||||
|
||||
* mkdemodirs: New
|
||||
* signdemokey: New.
|
||||
* Makefile.am (distclean-local): New.
|
||||
|
||||
Wed Mar 17 13:09:03 CET 1999 Werner Koch <wk@isil.d.shuttle.de>
|
||||
|
||||
* mds.test: replaced the "echo -n"
|
||||
|
||||
Mon Mar 8 20:47:17 CET 1999 Werner Koch <wk@isil.d.shuttle.de>
|
||||
|
||||
* pubdemo.asc, secdemo.asc: New.
|
||||
|
||||
Fri Feb 19 15:49:15 CET 1999 Werner Koch <wk@isil.d.shuttle.de>
|
||||
|
||||
* genkey1024.test: Be really quiet.
|
||||
|
||||
1999-01-01 Geoff Keating <geoffk@ozemail.com.au>
|
||||
|
||||
* Makefile.am (CLEANFILES): Also delete trustdb and any leftover
|
||||
lockfiles.
|
||||
|
||||
Fri Nov 27 15:30:24 CET 1998 Werner Koch <wk@isil.d.shuttle.de>
|
||||
|
||||
* clearsig.test: Some more test cases.
|
||||
|
||||
Sun Oct 25 18:19:35 1998 Werner Koch (wk@isil.d.shuttle.de)
|
||||
|
||||
* mds.test: Check whether TIGER is available.
|
||||
* sigs.tesr: Ditto.
|
||||
|
||||
Wed Sep 23 12:25:07 1998 Werner Koch (wk@isil.d.shuttle.de)
|
||||
|
||||
* run-gpg.patterns: New (because Solaris fgrep does not like -f -).
|
||||
|
||||
Mon Aug 10 21:33:38 1998 Werner Koch (wk@(none))
|
||||
|
||||
* genkey1024.test: Ariel fixed this.
|
||||
|
||||
Wed Jul 8 10:43:47 1998 Werner Koch (wk@isil.d.shuttle.de)
|
||||
|
||||
* seat.test: New.
|
||||
|
||||
Mon May 18 15:40:02 1998 Werner Koch (wk@isil.d.shuttle.de)
|
||||
|
||||
* Makefile.am: Now uses mk-tdata to produce random test data.
|
||||
|
||||
* ChangeLog: New.
|
||||
|
||||
|
||||
Copyright 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
|
||||
|
||||
This file is free software; as a special exception the author gives
|
||||
unlimited permission to copy and/or distribute it, with or without
|
||||
modifications, as long as this notice is preserved.
|
||||
|
||||
This file is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
|
||||
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
|
@ -1,100 +0,0 @@
|
||||
# Copyright (C) 1998, 1999, 2000, 2001, 2003 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is part of GnuPG.
|
||||
#
|
||||
# GnuPG is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# GnuPG is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
|
||||
# Process this file with automake to create Makefile.in
|
||||
|
||||
GPG_IMPORT = ../g10/gpg --homedir . --quiet --yes --no-permission-warning --import
|
||||
|
||||
TESTS = version.test mds.test \
|
||||
decrypt.test decrypt-dsa.test \
|
||||
sigs.test sigs-dsa.test \
|
||||
encrypt.test encrypt-dsa.test \
|
||||
seat.test clearsig.test encryptp.test detach.test \
|
||||
armsigs.test armencrypt.test armencryptp.test \
|
||||
signencrypt.test signencrypt-dsa.test \
|
||||
armsignencrypt.test armdetach.test \
|
||||
armdetachm.test detachm.test genkey1024.test \
|
||||
conventional.test conventional-mdc.test \
|
||||
multisig.test verify.test armor.test
|
||||
|
||||
|
||||
TEST_FILES = pubring.asc secring.asc plain-1o.asc plain-2o.asc plain-3o.asc \
|
||||
plain-1.asc plain-2.asc plain-3.asc plain-1-pgp.asc \
|
||||
pubring.pkr.asc secring.skr.asc secdemo.asc pubdemo.asc options
|
||||
|
||||
DATA_FILES = data-500 data-9000 data-32000 data-80000 plain-large
|
||||
|
||||
EXTRA_DIST = defs.inc $(TESTS) $(TEST_FILES) \
|
||||
mkdemodirs signdemokey
|
||||
CLEANFILES = prepared.stamp x y yy z out err $(DATA_FILES) \
|
||||
plain-1 plain-2 plain-3 trustdb.gpg *.lock .\#lk* \
|
||||
*.test.log gpg_dearmor gpg.conf \
|
||||
pubring.gpg secring.gpg pubring.pkr secring.skr
|
||||
DISTCLEANFILES = pubring.gpg~ random_seed
|
||||
|
||||
|
||||
all-local: prepared.stamp
|
||||
|
||||
distclean-local:
|
||||
$(srcdir)/mkdemodirs --clean
|
||||
|
||||
prepared.stamp: ./pubring.gpg ./secring.gpg ./plain-1 ./plain-2 ./plain-3 \
|
||||
./pubring.pkr ./secring.skr ./gpg_dearmor $(DATA_FILES)
|
||||
$(GPG_IMPORT) $(srcdir)/pubdemo.asc
|
||||
echo timestamp >./prepared.stamp
|
||||
|
||||
./gpg_dearmor:
|
||||
echo '#!/bin/sh' >./gpg_dearmor
|
||||
echo "../g10/gpg --no-options --no-greeting \
|
||||
--no-secmem-warning --batch --dearmor" >>./gpg_dearmor
|
||||
chmod 755 ./gpg_dearmor
|
||||
|
||||
./pubring.gpg: $(srcdir)/pubring.asc $(srcdir)/pubdemo.asc ./gpg_dearmor
|
||||
./gpg_dearmor > ./pubring.gpg < $(srcdir)/pubring.asc
|
||||
|
||||
./secring.gpg: $(srcdir)/secring.asc ./gpg_dearmor
|
||||
./gpg_dearmor > ./secring.gpg < $(srcdir)/secring.asc
|
||||
|
||||
./pubring.pkr: $(srcdir)/pubring.pkr.asc ./gpg_dearmor
|
||||
./gpg_dearmor > ./pubring.pkr < $(srcdir)/pubring.pkr.asc
|
||||
|
||||
./secring.skr: $(srcdir)/secring.skr.asc ./gpg_dearmor
|
||||
./gpg_dearmor > ./secring.skr < $(srcdir)/secring.skr.asc
|
||||
|
||||
./plain-1: $(srcdir)/plain-1o.asc ./gpg_dearmor
|
||||
./gpg_dearmor > ./plain-1 < $(srcdir)/plain-1o.asc
|
||||
|
||||
./plain-2: $(srcdir)/plain-2o.asc ./gpg_dearmor
|
||||
./gpg_dearmor > ./plain-2 < $(srcdir)/plain-2o.asc
|
||||
|
||||
./plain-3: $(srcdir)/plain-3o.asc ./gpg_dearmor
|
||||
./gpg_dearmor > ./plain-3 < $(srcdir)/plain-3o.asc
|
||||
|
||||
|
||||
data-500:
|
||||
../tools/mk-tdata 500 >data-500
|
||||
data-9000:
|
||||
../tools/mk-tdata 9000 >data-9000
|
||||
data-32000:
|
||||
../tools/mk-tdata 32000 >data-32000
|
||||
data-80000:
|
||||
../tools/mk-tdata 80000 >data-80000
|
||||
plain-large:
|
||||
cat $(srcdir)/../doc/HACKING \
|
||||
$(srcdir)/../doc/DETAILS \
|
||||
$(srcdir)/../doc/FAQ >plain-large
|
@ -1,11 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
. $srcdir/defs.inc || exit 3
|
||||
|
||||
|
||||
#info Checking armored detached signatures
|
||||
for i in $plain_files $data_files ; do
|
||||
echo "$usrpass1" | $GPG --passphrase-fd 0 -sab -o x --yes $i
|
||||
$GPG -o /dev/null --yes x <$i || error "$i: bad signature"
|
||||
done
|
||||
|
@ -1,9 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
. $srcdir/defs.inc || exit 3
|
||||
|
||||
#info Checking armored detached signatures of multiple files
|
||||
i="$plain_files $data_files"
|
||||
echo "$usrpass1" | $GPG --passphrase-fd 0 -sab -o x --yes $i
|
||||
cat $i | $GPG -o /dev/null --yes x || error "$i: bad signature"
|
||||
|
@ -1,11 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
. $srcdir/defs.inc || exit 3
|
||||
|
||||
#info Checking armored encryption
|
||||
for i in $plain_files $data_files ; do
|
||||
$GPG --always-trust -ea -o x --yes -r "$usrname2" $i
|
||||
$GPG -o y --yes x
|
||||
cmp $i y || error "$i: mismatch"
|
||||
done
|
||||
|
@ -1,12 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
. $srcdir/defs.inc || exit 3
|
||||
|
||||
#info Checking armored encryption with a pipe
|
||||
for i in $plain_files $data_files ; do
|
||||
$GPG --always-trust -ea --yes -r "$usrname2" < $i | tee x | $GPG -o y --yes
|
||||
cmp $i y || error "$i: mismatch"
|
||||
$GPG --yes < x > y
|
||||
cmp $i y || error "$i: mismatch"
|
||||
done
|
||||
|
@ -1,181 +0,0 @@
|
||||
#!/bin/sh
|
||||
# Regression tests pertaining to the armoring.
|
||||
|
||||
. $srcdir/defs.inc || exit 3
|
||||
|
||||
armored_key_8192='-----BEGIN PGP PUBLIC KEY BLOCK-----
|
||||
Version: SKS 1.0.9
|
||||
|
||||
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
|
||||
=oXxa
|
||||
-----END PGP PUBLIC KEY BLOCK-----
|
||||
'
|
||||
|
||||
# Bug solved 2005-04-07:
|
||||
# Try importing the attached key file. As the key is exactly 8192
|
||||
# bytes long, radix64_read is called twice - the first time to read
|
||||
# the 8192 bytes, and then once again, to handle the pad '=' on the
|
||||
# last four character radix64 block '0uI='. gpg bails out with
|
||||
# gpg: [don't know]: invalid packet (ctb=2d)
|
||||
# On a read for only the = sign, radix64_read returns -1 for EOF.
|
||||
# This causes the iobuf code to pop the armor filter and thus the next
|
||||
# byte read is the '-' from the END header line, causing an error.
|
||||
i=armored_key_8192
|
||||
info "checking: $i"
|
||||
eval "(IFS=; echo \"\$$i\")" >x
|
||||
$GPG --import x || error "the $i bug is back in town"
|
||||
|
||||
|
||||
|
||||
|
@ -1,13 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
. $srcdir/defs.inc || exit 3
|
||||
|
||||
|
||||
#info Checking armored signing and encryption
|
||||
for i in $plain_files $data_files ; do
|
||||
echo "$usrpass1" | $GPG --passphrase-fd 0 --always-trust \
|
||||
-sae -o x --yes -r "$usrname2" $i
|
||||
$GPG -o y --yes x
|
||||
cmp $i y || error "$i: mismatch"
|
||||
done
|
||||
|
@ -1,11 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
. $srcdir/defs.inc || exit 3
|
||||
|
||||
#info Checking armored signatures
|
||||
for i in $plain_files $data_files ; do
|
||||
echo "$usrpass1" | $GPG --passphrase-fd 0 -sa -o x --yes $i
|
||||
$GPG -o y --yes x
|
||||
cmp $i y || error "$i: mismatch"
|
||||
done
|
||||
|
@ -1,102 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
# Fixme: we should not only do a --verify but also the output.
|
||||
|
||||
. $srcdir/defs.inc || exit 3
|
||||
|
||||
# ======================================
|
||||
# I can't compare the out because plain-3 has no LF as last charcater
|
||||
# but the output has always one. I do not thinkl this is a bug, because
|
||||
# it is clear text and not binary text.
|
||||
# ======================================
|
||||
for i in $plain_files plain-large ; do
|
||||
echo "$usrpass1" | $GPG --passphrase-fd 0 -sat -o x --yes $i
|
||||
$GPG --verify x
|
||||
done
|
||||
|
||||
|
||||
# ======================================
|
||||
# and once more to check rfc1991
|
||||
# ======================================
|
||||
|
||||
if have_pubkey_algo "RSA"; then
|
||||
for i in $plain_files plain-large ; do
|
||||
$GPG -u $usrname3 --rfc1991 --digest-algo md5 -sat -o x --yes $i
|
||||
$GPG --verify x
|
||||
done
|
||||
fi
|
||||
|
||||
# ======================================
|
||||
# and one with long lines
|
||||
# ======================================
|
||||
cat >y <<EOF
|
||||
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxyx
|
||||
|
||||
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
||||
EOF
|
||||
echo "$usrpass1" | $GPG --passphrase-fd 0 --clearsign -o x --yes y
|
||||
$GPG --verify x
|
||||
|
||||
|
||||
# ======================================
|
||||
# and one with only one long lines
|
||||
# ======================================
|
||||
cat >y <<EOF
|
||||
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxyx
|
||||
EOF
|
||||
echo "$usrpass1" | $GPG --passphrase-fd 0 --clearsign -o x --yes y
|
||||
$GPG --verify x
|
||||
|
||||
|
||||
# ======================================
|
||||
# and one with an empty body
|
||||
# ======================================
|
||||
cat >y <<EOF
|
||||
EOF
|
||||
echo "$usrpass1" | $GPG --passphrase-fd 0 --clearsign -o x --yes y
|
||||
$GPG --verify x
|
||||
|
||||
|
||||
# ======================================
|
||||
# and one with one empty line at the end
|
||||
# ======================================
|
||||
cat >y <<EOF
|
||||
line 1
|
||||
line 2
|
||||
line 3
|
||||
there is a blank line after this
|
||||
|
||||
EOF
|
||||
echo "$usrpass1" | $GPG --passphrase-fd 0 --clearsign -o x --yes y
|
||||
$GPG --verify x
|
||||
|
||||
|
||||
# ======================================
|
||||
# I think this file will be constructed wrong (gpg 0.9.3)
|
||||
# but it should verify okay anyway.
|
||||
# ======================================
|
||||
echo "this is a sig test" >y
|
||||
echo_n " " >>y
|
||||
echo "$usrpass1" | $GPG --passphrase-fd 0 --clearsign -o x --yes y
|
||||
$GPG --verify x
|
||||
|
||||
|
||||
# ======================================
|
||||
# check our special diff mode
|
||||
# ======================================
|
||||
cat >y <<EOF
|
||||
--- mainproc.c Tue Jun 27 09:28:11 2000
|
||||
+++ mainproc.c~ Thu Jun 8 22:50:25 2000
|
||||
@@ -1190,16 +1190,13 @@
|
||||
md_enable( c->mfx.md, n1->pkt->pkt.signature->digest_algo);
|
||||
}
|
||||
/* ask for file and hash it */
|
||||
- if( c->sigs_only ) {
|
||||
+ if( c->sigs_only )
|
||||
rc = hash_datafiles( c->mfx.md, NULL,
|
||||
c->signed_data, c->sigfilename,
|
||||
n1? (n1->pkt->pkt.onepass_sig->sig_class == 0x01):0 );
|
||||
EOF
|
||||
echo "$usrpass1" | $GPG --passphrase-fd 0 \
|
||||
--not-dash-escaped --clearsign -o x --yes y
|
||||
$GPG --verify x
|
@ -1,42 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
. $srcdir/defs.inc || exit 3
|
||||
|
||||
algos="3des"
|
||||
|
||||
if have_cipher_algo "idea"; then
|
||||
algos="$algos idea"
|
||||
fi
|
||||
|
||||
if have_cipher_algo "cast5"; then
|
||||
algos="$algos idea"
|
||||
fi
|
||||
|
||||
if have_cipher_algo "blowfish"; then
|
||||
algos="$algos idea"
|
||||
fi
|
||||
|
||||
if have_cipher_algo "aes"; then
|
||||
algos="$algos aes aes192 aes256"
|
||||
fi
|
||||
|
||||
if have_cipher_algo "twofish"; then
|
||||
algos="$algos twofish"
|
||||
fi
|
||||
|
||||
#info Checking conventional encryption
|
||||
for i in 0 1 2 3 9 10 11 19 20 21 22 23 39 40 41 8192 32000 ; do
|
||||
for ciph in $algos; do
|
||||
# *BSD's dd can't cope with a count of 0
|
||||
if test "$i" = "0"; then
|
||||
: >z
|
||||
else
|
||||
dd if=data-80000 of=z bs=1 count=$i 2>/dev/null
|
||||
fi
|
||||
echo "Hier spricht HAL" | $GPG --passphrase-fd 0 \
|
||||
--force-mdc --cipher $ciph -c -o x --yes z
|
||||
echo "Hier spricht HAL" | $GPG --passphrase-fd 0 \
|
||||
-o y --yes x
|
||||
cmp z y || error "$ciph/$i: mismatch"
|
||||
done
|
||||
done
|
@ -1,37 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
. $srcdir/defs.inc || exit 3
|
||||
|
||||
#info Checking conventional encryption
|
||||
for i in plain-2 data-32000 ; do
|
||||
echo "Hier spricht HAL" | $GPG --passphrase-fd 0 -c -o x --yes $i
|
||||
echo "Hier spricht HAL" | $GPG --passphrase-fd 0 -o y --yes x
|
||||
cmp $i y || error "$i: mismatch"
|
||||
done
|
||||
|
||||
algos="3des"
|
||||
|
||||
if have_cipher_algo "CAST5"; then
|
||||
algos="$algos cast5"
|
||||
fi
|
||||
|
||||
if have_cipher_algo "BLOWFISH"; then
|
||||
algos="$algos blowfish"
|
||||
fi
|
||||
|
||||
if have_cipher_algo "AES"; then
|
||||
algos="$algos aes aes192 aes256"
|
||||
fi
|
||||
|
||||
if have_cipher_algo "TWOFISH"; then
|
||||
algos="$algos twofish"
|
||||
fi
|
||||
|
||||
for a in $algos; do
|
||||
for i in plain-1 data-80000 ; do
|
||||
echo "Hier spricht HAL" | $GPG --passphrase-fd 0 \
|
||||
--cipher-algo $a -c -o x --yes $i
|
||||
echo "Hier spricht HAL" | $GPG --passphrase-fd 0 -o y --yes x
|
||||
cmp $i y || error "$i: ($a) mismatch"
|
||||
done
|
||||
done
|
@ -1,10 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
. $srcdir/defs.inc || exit 3
|
||||
|
||||
#info Checking decryption of supplied DSA encrypted file
|
||||
for i in "plain-1" ; do
|
||||
$GPG $dsa_keyrings -o y --yes $srcdir/$i-pgp.asc
|
||||
cmp $i y || error "$i: mismatch"
|
||||
done
|
||||
|
@ -1,10 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
. $srcdir/defs.inc || exit 3
|
||||
|
||||
#info Checking decryption of supplied files
|
||||
for i in $plain_files ; do
|
||||
echo "$usrpass1" | $GPG --passphrase-fd 0 -o y --yes $srcdir/$i.asc
|
||||
cmp $i y || error "$i: mismatch"
|
||||
done
|
||||
|
162
checks/defs.inc
@ -1,162 +0,0 @@
|
||||
# definitions for the check scripts
|
||||
|
||||
#--------------------------------
|
||||
#------ constants ---------------
|
||||
#--------------------------------
|
||||
|
||||
# Note that usrpass1 is also used in Makefile.am
|
||||
usrname1="one"
|
||||
usrpass1="def"
|
||||
usrname2="two"
|
||||
usrpass2=""
|
||||
usrname3="three"
|
||||
usrpass3=""
|
||||
|
||||
|
||||
dsa_usrname1="pgp5"
|
||||
# we use the sub key because we do not yet have the logic to
|
||||
# to derive the first encryption key from a keyblock (I guess)
|
||||
dsa_usrname2="0xCB879DE9"
|
||||
|
||||
dsa_keyrings="--keyring ./pubring.pkr --secret-keyring ./secring.skr"
|
||||
|
||||
|
||||
plain_files="plain-1 plain-2 plain-3"
|
||||
data_files="data-500 data-9000 data-32000 data-80000"
|
||||
exp_files=""
|
||||
|
||||
# The testscripts expect the original language
|
||||
LANG=
|
||||
LANGUAGE=
|
||||
LC_ALL=
|
||||
LC_MESSAGES=
|
||||
|
||||
# Internal use.
|
||||
defs_stop_on_error=no
|
||||
defs_error_seen=no
|
||||
|
||||
#--------------------------------
|
||||
#------ utility functions -------
|
||||
#--------------------------------
|
||||
|
||||
fatal () {
|
||||
echo "$pgmname: fatal:" $* >&2
|
||||
echo "$pgmname: fatal:" $* >&5
|
||||
exit 1;
|
||||
}
|
||||
|
||||
error () {
|
||||
echo "$pgmname:" $* >&2
|
||||
defs_error_seen=yes
|
||||
echo "$pgmname:" $* >&5
|
||||
if [ x$defs_stop_on_error != xyes ]; then
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Call this at the start of a test and resume_error at the end to keep
|
||||
# on running all subtests without immediately exiting on error.
|
||||
suspend_error () {
|
||||
defs_stop_on_error=yes
|
||||
}
|
||||
|
||||
resume_error () {
|
||||
if [ x$defs_error_seen = xyes ]; then
|
||||
exit 1
|
||||
fi
|
||||
defs_stop_on_error=no
|
||||
defs_error_seen=no
|
||||
}
|
||||
|
||||
info () {
|
||||
echo "$pgmname:" $* >&2
|
||||
if [ -n "${verbose+set}" ]; then
|
||||
echo "$pgmname:" $* >&5
|
||||
fi
|
||||
}
|
||||
|
||||
linefeed () {
|
||||
echo >&2
|
||||
}
|
||||
|
||||
|
||||
echo_n_init=no
|
||||
echo_n () {
|
||||
if test "$echo_n_init" = "no"; then
|
||||
if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then
|
||||
if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then
|
||||
echo_n_n=
|
||||
echo_n_c='
|
||||
'
|
||||
else
|
||||
echo_n_n='-n'
|
||||
echo_n_c=
|
||||
fi
|
||||
else
|
||||
echo_n_n=
|
||||
echo_n_c='\c'
|
||||
fi
|
||||
echo_n_init=yes
|
||||
fi
|
||||
echo $echo_n_n "${1}$echo_n_c"
|
||||
}
|
||||
|
||||
|
||||
#cleanup () {
|
||||
# rm $cleanup_files 2>/dev/null || true
|
||||
# echo "#empty" >./options
|
||||
#}
|
||||
|
||||
|
||||
#add_cleanup () {
|
||||
# cleanup_files="$cleanup_files $*"
|
||||
#}
|
||||
|
||||
have_pubkey_algo () {
|
||||
if ../g10/gpg --homedir . --version | grep "Pubkey:.*$1" >/dev/null
|
||||
then
|
||||
true
|
||||
else
|
||||
false
|
||||
fi
|
||||
}
|
||||
|
||||
have_cipher_algo () {
|
||||
if ../g10/gpg --homedir . --version | grep "Cipher:.*$1" >/dev/null
|
||||
then
|
||||
true
|
||||
else
|
||||
false
|
||||
fi
|
||||
}
|
||||
|
||||
have_hash_algo () {
|
||||
if ../g10/gpg --homedir . --version | grep "Hash:.*$1" >/dev/null
|
||||
then
|
||||
true
|
||||
else
|
||||
false
|
||||
fi
|
||||
}
|
||||
|
||||
set -e
|
||||
pgmname=`basename $0`
|
||||
#trap cleanup SIGHUP SIGINT SIGQUIT
|
||||
|
||||
[ -z "$srcdir" ] && fatal "not called from make"
|
||||
|
||||
# Make sure we have a valid option files even with VPATH builds.
|
||||
if [ -f ./options ]; then
|
||||
:
|
||||
elif [ -f ./gpg.conf ]; then
|
||||
:
|
||||
elif [ -f $srcdir/options ]; then
|
||||
cat $srcdir/options >gpg.conf
|
||||
fi
|
||||
|
||||
GPG="../g10/gpg --no-permission-warning --homedir . "
|
||||
|
||||
exec 5>&2 2>${pgmname}.log
|
||||
|
||||
:
|
||||
# end
|
@ -1,10 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
. $srcdir/defs.inc || exit 3
|
||||
|
||||
#info Checking detached signatures
|
||||
for i in $plain_files $data_files ; do
|
||||
echo "$usrpass1" | $GPG --passphrase-fd 0 -sb -o x --yes $i
|
||||
$GPG -o /dev/null --yes x <$i || error "$i: bad signature"
|
||||
done
|
||||
|
@ -1,9 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
. $srcdir/defs.inc || exit 3
|
||||
|
||||
#info Checking detached signatures of multiple files
|
||||
i="$plain_files $data_files"
|
||||
echo "$usrpass1" | $GPG --passphrase-fd 0 -sb -o x --yes $i
|
||||
cat $i | $GPG -o /dev/null --yes x || error "$i: bad signature"
|
||||
|
@ -1,41 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
. $srcdir/defs.inc || exit 3
|
||||
|
||||
#info Checking encryption
|
||||
for i in $plain_files $data_files ; do
|
||||
$GPG $dsa_keyrings --always-trust -e -o x --yes -r "$dsa_usrname2" $i
|
||||
$GPG $dsa_keyrings -o y --yes x
|
||||
cmp $i y || error "$i: mismatch"
|
||||
done
|
||||
|
||||
algos="3des"
|
||||
|
||||
if have_cipher_algo "idea"; then
|
||||
algos="$algos idea"
|
||||
fi
|
||||
|
||||
if have_cipher_algo "cast5"; then
|
||||
algos="$algos idea"
|
||||
fi
|
||||
|
||||
if have_cipher_algo "blowfish"; then
|
||||
algos="$algos idea"
|
||||
fi
|
||||
|
||||
if have_cipher_algo "aes"; then
|
||||
algos="$algos aes aes192 aes256"
|
||||
fi
|
||||
|
||||
if have_cipher_algo "twofish"; then
|
||||
algos="$algos twofish"
|
||||
fi
|
||||
|
||||
for ca in $algos ; do
|
||||
for i in $plain_files $data_files ; do
|
||||
$GPG $dsa_keyrings --always-trust --cipher-algo $ca -e \
|
||||
-o x --yes -r "$dsa_usrname2" $i
|
||||
$GPG $dsa_keyrings -o y --yes x
|
||||
cmp $i y || error "$i: mismatch"
|
||||
done
|
||||
done
|
@ -1,40 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
. $srcdir/defs.inc || exit 3
|
||||
|
||||
#info Checking encryption
|
||||
for i in $plain_files $data_files ; do
|
||||
$GPG --always-trust -e -o x --yes -r "$usrname2" $i
|
||||
$GPG -o y --yes x
|
||||
cmp $i y || error "$i: mismatch"
|
||||
done
|
||||
|
||||
algos="3des"
|
||||
|
||||
if have_cipher_algo "idea"; then
|
||||
algos="$algos idea"
|
||||
fi
|
||||
|
||||
if have_cipher_algo "cast5"; then
|
||||
algos="$algos idea"
|
||||
fi
|
||||
|
||||
if have_cipher_algo "blowfish"; then
|
||||
algos="$algos idea"
|
||||
fi
|
||||
|
||||
if have_cipher_algo "aes"; then
|
||||
algos="$algos aes aes192 aes256"
|
||||
fi
|
||||
|
||||
if have_cipher_algo "twofish"; then
|
||||
algos="$algos twofish"
|
||||
fi
|
||||
|
||||
for ca in $algos ; do
|
||||
for i in $plain_files $data_files ; do
|
||||
$GPG --always-trust -e -o x --yes -r "$usrname2" --cipher-algo $ca $i
|
||||
$GPG -o y --yes x
|
||||
cmp $i y || error "$i: mismatch"
|
||||
done
|
||||
done
|
@ -1,10 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
. $srcdir/defs.inc || exit 3
|
||||
|
||||
#info Checking encryption with a pipe
|
||||
for i in $plain_files $data_files ; do
|
||||
$GPG --always-trust -e --yes -r "$usrname2" <$i | $GPG --yes > y
|
||||
cmp $i y || error "$i: mismatch"
|
||||
done
|
||||
|
@ -1,30 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
. $srcdir/defs.inc || exit 3
|
||||
|
||||
../g10/gpg --quiet --batch --quick-random --homedir . --gen-key <<EOF
|
||||
Key-Type: DSA
|
||||
Key-Length: 1024
|
||||
Subkey-Type: ELG-E
|
||||
Subkey-Length: 1024
|
||||
Name-Real: Harry H.
|
||||
Name-Comment: test key
|
||||
Name-Email: hh@@ddorf.de
|
||||
Expire-Date: 1
|
||||
Passphrase: abc
|
||||
%commit
|
||||
EOF
|
||||
|
||||
if have_pubkey_algo "RSA"; then
|
||||
../g10/gpg --quiet --batch --quick-random --homedir . --gen-key <<EOF
|
||||
Key-Type: RSA
|
||||
Key-Length: 1024
|
||||
Key-Usage: sign,encrypt
|
||||
Name-Real: Harry A.
|
||||
Name-Comment: RSA test key
|
||||
Name-Email: hh@@ddorf.de
|
||||
Expire-Date: 2
|
||||
Passphrase: abc
|
||||
%commit
|
||||
EOF
|
||||
fi
|
@ -1,69 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
|
||||
. $srcdir/defs.inc || exit 3
|
||||
|
||||
|
||||
test_one () {
|
||||
if [ "`grep $1 y | sed -e 's/:[^:]*:\(.*\):/\1/'`" != "$2" ]; then
|
||||
failed="$failed $1"
|
||||
fi
|
||||
}
|
||||
|
||||
failed=""
|
||||
|
||||
#info Checking message digests
|
||||
cat /dev/null | $GPG --with-colons --print-mds >y
|
||||
# MD5
|
||||
test_one ":1:" "D41D8CD98F00B204E9800998ECF8427E"
|
||||
# SHA-1
|
||||
test_one ":2:" "DA39A3EE5E6B4B0D3255BFEF95601890AFD80709"
|
||||
# RMD160
|
||||
test_one ":3:" "9C1185A5C5E9FC54612808977EE8F548B2258D31"
|
||||
# SHA-224
|
||||
if have_hash_algo "SHA224"; then
|
||||
test_one ":11:" "D14A028C2A3A2BC9476102BB288234C415A2B01F828EA62AC5B3E42F"
|
||||
else
|
||||
echo "Hash algorithm SHA-224 is not installed (not an error)"
|
||||
fi
|
||||
# SHA-256
|
||||
if have_hash_algo "SHA256"; then
|
||||
test_one ":8:" "E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855"
|
||||
else
|
||||
echo "Hash algorithm SHA-256 is not installed (not an error)"
|
||||
fi
|
||||
# SHA-384
|
||||
if have_hash_algo "SHA384"; then
|
||||
test_one ":9:" "38B060A751AC96384CD9327EB1B1E36A21FDB71114BE07434C0CC7BF63F6E1DA274EDEBFE76F65FBD51AD2F14898B95B"
|
||||
else
|
||||
echo "Hash algorithm SHA-384 is not installed (not an error)"
|
||||
fi
|
||||
# SHA-512
|
||||
if have_hash_algo "SHA512"; then
|
||||
test_one ":10:" "CF83E1357EEFB8BDF1542850D66D8007D620E4050B5715DC83F4A921D36CE9CE47D0D13C5D85F2B0FF8318D2877EEC2F63B931BD47417A81A538327AF927DA3E"
|
||||
else
|
||||
echo "Hash algorithm SHA-512 is not installed (not an error)"
|
||||
fi
|
||||
|
||||
[ "$failed" != "" ] && error "$failed failed for empty string"
|
||||
|
||||
echo_n "abcdefghijklmnopqrstuvwxyz" | $GPG --with-colons --print-mds >y
|
||||
test_one ":1:" "C3FCD3D76192E4007DFB496CCA67E13B"
|
||||
test_one ":2:" "32D10C7B8CF96570CA04CE37F2A19D84240D3A89"
|
||||
test_one ":3:" "F71C27109C692C1B56BBDCEB5B9D2865B3708DBC"
|
||||
if have_hash_algo "SHA224"; then
|
||||
test_one ":11:" "45A5F72C39C5CFF2522EB3429799E49E5F44B356EF926BCF390DCCC2"
|
||||
fi
|
||||
if have_hash_algo "SHA256"; then
|
||||
test_one ":8:" "71C480DF93D6AE2F1EFAD1447C66C9525E316218CF51FC8D9ED832F2DAF18B73"
|
||||
fi
|
||||
if have_hash_algo "SHA384"; then
|
||||
test_one ":9:" "FEB67349DF3DB6F5924815D6C3DC133F091809213731FE5C7B5F4999E463479FF2877F5F2936FA63BB43784B12F3EBB4"
|
||||
fi
|
||||
if have_hash_algo "SHA512"; then
|
||||
test_one ":10:" "4DBFF86CC2CA1BAE1E16468A05CB9881C97F1753BCE3619034898FAA1AABE429955A1BF8EC483D7421FE3C1646613A59ED5441FB0F321389F77F48A879C7B1F1"
|
||||
fi
|
||||
|
||||
[ "$failed" != "" ] && error "$failed failed for a..z"
|
||||
|
||||
exit 0
|
@ -1,37 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
set -e
|
||||
|
||||
GPG="../g10/gpg --batch --quiet --no-secmem-warning --allow-secret-key-import"
|
||||
NAMES='Alpha Bravo Charlie Delta Echo Foxtrot Golf Hotel India
|
||||
Juliet Kilo Lima Mike November Oscar Papa Quebec Romeo
|
||||
Sierra Tango Uniform Victor Whisky XRay Yankee Zulu'
|
||||
|
||||
if [ "$1" = "--clean" ]; then
|
||||
(for i in $NAMES; do
|
||||
[ -d $i ] && rm -r $i
|
||||
done) || true
|
||||
exit 0
|
||||
fi
|
||||
|
||||
$GPG --dearmor -o secdemo.gpg --yes ../checks/secdemo.asc
|
||||
$GPG --dearmor -o pubdemo.gpg --yes ../checks/pubdemo.asc
|
||||
[ -f ./tdb.tmp ] && rm ./tdb.tmp
|
||||
GPGDEMO="$GPG --homedir . --trustdb-name ./tdb.tmp --no-default-keyring
|
||||
--keyring pubdemo.gpg --secret-keyring secdemo.gpg"
|
||||
echo -n "Creating:"
|
||||
for name in $NAMES; do
|
||||
echo -n " $name"
|
||||
[ -d $name ] && rm -r $name
|
||||
mkdir $name
|
||||
$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 "."
|
||||
[ -f ./tdb.tmp ] && rm ./tdb.tmp
|
||||
rm pubdemo.gpg secdemo.gpg
|
||||
|
||||
|
@ -1,145 +0,0 @@
|
||||
#!/bin/sh
|
||||
# Check that gpg verifies only signatures where there is no ambiguity
|
||||
# in the order of packets. Needs the Demo Keys Lima and Mike.
|
||||
|
||||
# Note: We do son't support multiple signaturess anymore thus thsi test is
|
||||
# not really needed becuase verify could do the same. We keep it anyway.
|
||||
|
||||
. $srcdir/defs.inc || exit 3
|
||||
|
||||
suspend_error
|
||||
|
||||
|
||||
|
||||
sig_1ls1ls_valid='
|
||||
-----BEGIN PGP ARMORED FILE-----
|
||||
|
||||
kA0DAAIRN8q1H7eRA/gBrCdiBXRleHQxOogq9EkgYW0gc29ycnksIEkgY2FuJ3Qg
|
||||
ZG8gdGhhdAqIPwMFADqIKvQ3yrUft5ED+BEC2joAoJaSaXOZEtSZqQ780HIXG77e
|
||||
8PB7AJ4wCprmaFTO0fBaTcXDuEOBdAWnOZANAwACETfKtR+3kQP4AawnYgV0ZXh0
|
||||
MTqIKvRJIGFtIHNvcnJ5LCBJIGNhbid0IGRvIHRoYXQKiD8DBQA6iCr0N8q1H7eR
|
||||
A/gRAto6AKCWkmlzmRLUmakO/NByFxu+3vDwewCeMAqa5mhUztHwWk3Fw7hDgXQF
|
||||
pzk=
|
||||
=8jSC
|
||||
-----END PGP ARMORED FILE-----
|
||||
'
|
||||
sig_ls_valid='
|
||||
-----BEGIN PGP ARMORED FILE-----
|
||||
|
||||
rCdiBXRleHQxOogrS0kgYW0gc29ycnksIEkgY2FuJ3QgZG8gdGhhdAqIPwMFADqI
|
||||
K0s3yrUft5ED+BECLQMAn2jZUNOpB4OuurSQkc2TRfg6ek02AJ9+oJS0frQ+yUsT
|
||||
QDUFTH2PvZRxjw==
|
||||
=J+lb
|
||||
-----END PGP ARMORED FILE-----
|
||||
'
|
||||
sig_sl_valid='
|
||||
-----BEGIN PGP ARMORED FILE-----
|
||||
|
||||
iD8DBQA6iCtLN8q1H7eRA/gRAi0DAJ9o2VDTqQeDrrq0kJHNk0X4OnpNNgCffqCU
|
||||
tH60PslLE0A1BUx9j72UcY+sJ2IFdGV4dDE6iCtLSSBhbSBzb3JyeSwgSSBjYW4n
|
||||
dCBkbyB0aGF0Cg==
|
||||
=N9MP
|
||||
-----END PGP ARMORED FILE-----
|
||||
'
|
||||
sig_11lss_valid_but_is_not='
|
||||
-----BEGIN PGP ARMORED FILE-----
|
||||
|
||||
kA0DAAIRN8q1H7eRA/gAkA0DAAIRN8q1H7eRA/gBrCdiBXRleHQxOogyXUkgYW0g
|
||||
c29ycnksIEkgY2FuJ3QgZG8gdGhhdAqIPwMFADqIMl03yrUft5ED+BECwQAAnRXT
|
||||
mXjVd385oD38W80XuheWKTGcAJ9pZ6/flaKDfw+SLido7xaUHuhp5Yg/AwUAOogy
|
||||
XTfKtR+3kQP4EQLBAACgnN0IP+NztE0aAc/DZ17yHWR9diwAniN0P01WmbgZJoZB
|
||||
Q341WRXKS/at
|
||||
=Ekrs
|
||||
-----END PGP ARMORED FILE-----
|
||||
'
|
||||
sig_11lss11lss_valid_but_is_not='
|
||||
-----BEGIN PGP ARMORED FILE-----
|
||||
|
||||
kA0DAAIRN8q1H7eRA/gAkA0DAAIRN8q1H7eRA/gBrCdiBXRleHQxOogyXUkgYW0g
|
||||
c29ycnksIEkgY2FuJ3QgZG8gdGhhdAqIPwMFADqIMl03yrUft5ED+BECwQAAnRXT
|
||||
mXjVd385oD38W80XuheWKTGcAJ9pZ6/flaKDfw+SLido7xaUHuhp5Yg/AwUAOogy
|
||||
XTfKtR+3kQP4EQLBAACgnN0IP+NztE0aAc/DZ17yHWR9diwAniN0P01WmbgZJoZB
|
||||
Q341WRXKS/atkA0DAAIRN8q1H7eRA/gAkA0DAAIRN8q1H7eRA/gBrCdiBXRleHQx
|
||||
OogyXUkgYW0gc29ycnksIEkgY2FuJ3QgZG8gdGhhdAqIPwMFADqIMl03yrUft5ED
|
||||
+BECwQAAnRXTmXjVd385oD38W80XuheWKTGcAJ9pZ6/flaKDfw+SLido7xaUHuhp
|
||||
5Yg/AwUAOogyXTfKtR+3kQP4EQLBAACgnN0IP+NztE0aAc/DZ17yHWR9diwAniN0
|
||||
P01WmbgZJoZBQ341WRXKS/at
|
||||
=P1Mu
|
||||
-----END PGP ARMORED FILE-----
|
||||
'
|
||||
sig_ssl_valid_but_is_not='
|
||||
-----BEGIN PGP ARMORED FILE-----
|
||||
|
||||
iD8DBQA6iCtLN8q1H7eRA/gRAi0DAJ9o2VDTqQeDrrq0kJHNk0X4OnpNNgCffqCU
|
||||
tH60PslLE0A1BUx9j72UcY+IPwMFADqIK0s3yrUft5ED+BECLQMAn2jZUNOpB4Ou
|
||||
urSQkc2TRfg6ek02AJ9+oJS0frQ+yUsTQDUFTH2PvZRxj6wnYgV0ZXh0MTqIK0tJ
|
||||
IGFtIHNvcnJ5LCBJIGNhbid0IGRvIHRoYXQK
|
||||
=Zven
|
||||
-----END PGP ARMORED FILE-----
|
||||
'
|
||||
sig_1lsls_invalid='
|
||||
-----BEGIN PGP ARMORED FILE-----
|
||||
|
||||
kA0DAAIRN8q1H7eRA/gBrCdiBXRleHQxOogq9EkgYW0gc29ycnksIEkgY2FuJ3Qg
|
||||
ZG8gdGhhdAqIPwMFADqIKvQ3yrUft5ED+BEC2joAoJaSaXOZEtSZqQ780HIXG77e
|
||||
8PB7AJ4wCprmaFTO0fBaTcXDuEOBdAWnOawnYgV0ZXh0MTqIK0tJIGFtIHNvcnJ5
|
||||
LCBJIGNhbid0IGRvIHRoYXQKiD8DBQA6iCtLN8q1H7eRA/gRAi0DAJ9o2VDTqQeD
|
||||
rrq0kJHNk0X4OnpNNgCffqCUtH60PslLE0A1BUx9j72UcY8=
|
||||
=nkeu
|
||||
-----END PGP ARMORED FILE-----
|
||||
'
|
||||
sig_lsls_invalid='
|
||||
-----BEGIN PGP ARMORED FILE-----
|
||||
|
||||
rCdiBXRleHQxOogrS0kgYW0gc29ycnksIEkgY2FuJ3QgZG8gdGhhdAqIPwMFADqI
|
||||
K0s3yrUft5ED+BECLQMAn2jZUNOpB4OuurSQkc2TRfg6ek02AJ9+oJS0frQ+yUsT
|
||||
QDUFTH2PvZRxj6wnYgV0ZXh0MTqIK0tJIGFtIHNvcnJ5LCBJIGNhbid0IGRvIHRo
|
||||
YXQKiD8DBQA6iCtLN8q1H7eRA/gRAi0DAJ9o2VDTqQeDrrq0kJHNk0X4OnpNNgCf
|
||||
fqCUtH60PslLE0A1BUx9j72UcY8=
|
||||
=BlZH
|
||||
-----END PGP ARMORED FILE-----
|
||||
'
|
||||
sig_lss_invalid='
|
||||
-----BEGIN PGP ARMORED FILE-----
|
||||
|
||||
rCdiBXRleHQxOogrS0kgYW0gc29ycnksIEkgY2FuJ3QgZG8gdGhhdAqIPwMFADqI
|
||||
K0s3yrUft5ED+BECLQMAn2jZUNOpB4OuurSQkc2TRfg6ek02AJ9+oJS0frQ+yUsT
|
||||
QDUFTH2PvZRxj4g/AwUAOogrSzfKtR+3kQP4EQItAwCfaNlQ06kHg666tJCRzZNF
|
||||
+Dp6TTYAn36glLR+tD7JSxNANQVMfY+9lHGP
|
||||
=jmt6
|
||||
-----END PGP ARMORED FILE-----
|
||||
'
|
||||
sig_slsl_invalid='
|
||||
-----BEGIN PGP ARMORED FILE-----
|
||||
|
||||
iD8DBQA6iCtLN8q1H7eRA/gRAi0DAJ9o2VDTqQeDrrq0kJHNk0X4OnpNNgCffqCU
|
||||
tH60PslLE0A1BUx9j72UcY+sJ2IFdGV4dDE6iCtLSSBhbSBzb3JyeSwgSSBjYW4n
|
||||
dCBkbyB0aGF0Cog/AwUAOogrSzfKtR+3kQP4EQItAwCfaNlQ06kHg666tJCRzZNF
|
||||
+Dp6TTYAn36glLR+tD7JSxNANQVMfY+9lHGPrCdiBXRleHQxOogrS0kgYW0gc29y
|
||||
cnksIEkgY2FuJ3QgZG8gdGhhdAo=
|
||||
=phBF
|
||||
-----END PGP ARMORED FILE-----
|
||||
'
|
||||
|
||||
|
||||
for i in sig_sl_valid ; do
|
||||
eval "(IFS=; echo \"\$$i\")" | ./gpg_dearmor >x
|
||||
$GPG --verify x 2>/dev/null || error "valid is invalid ($i)"
|
||||
linefeed
|
||||
done
|
||||
#for i in "$sig_11lss_valid_but_is_not" "$sig_11lss11lss_valid_but_is_not" \
|
||||
# "$sig_ssl_valid_but_is_not"; do
|
||||
# echo "$i" | $GPG --dearmor >x
|
||||
# $GPG --verify <x 2>/dev/null || error "valid is invalid"
|
||||
#done
|
||||
|
||||
for i in sig_1ls1ls_valid sig_ls_valid \
|
||||
sig_1lsls_invalid sig_lsls_invalid \
|
||||
sig_lss_invalid sig_slsl_invalid ; do
|
||||
eval "(IFS=; echo \"\$$i\")" | ./gpg_dearmor >x
|
||||
$GPG --verify <x 2>/dev/null && error "invalid is valid ($i)"
|
||||
linefeed
|
||||
done
|
||||
|
||||
|
||||
resume_error
|
@ -1,5 +0,0 @@
|
||||
no-greeting
|
||||
no-secmem-warning
|
||||
no-permission-warning
|
||||
batch
|
||||
no-auto-check-trustdb
|
@ -1,14 +0,0 @@
|
||||
Type Bits/KeyID Date User ID
|
||||
pub 888/A50283F1 2001/11/08 pgp2.6.3-test-key
|
||||
|
||||
-----BEGIN PGP PUBLIC KEY BLOCK-----
|
||||
Version: 2.6.3a
|
||||
|
||||
mQB8AzvqRosAAAEDeNMKLJMJQeGC2RG5Nec6R2mzC12N1wGLiYYJCsmSQd1Y8mht
|
||||
A2Sc+4k/q5+l6GHtfqUR/RTCIIudAZUzrQVIMhHDKF+5de9lsE5QxQS1u43QGVCb
|
||||
/9IYrOLOizYQ2pkBtD9LCrf7W2DccMEkpQKD8QAFE7QRcGdwMi42LjMtdGVzdC1r
|
||||
ZXmJAIQDBRA76kaL3HDBJKUCg/EBAZMoA3Yqqdix6B2RAzywi9bKSLqwAFVL+MMw
|
||||
W+BnYeBXF9u+bPpQvtyxgi0vx8F9r84B3HAhZNEjBWODF6vctIQhXhAhXIniDTSj
|
||||
HNzQ/+nbWnebQn18XUV2SdM1PzMOblD+nISte7+WUfWzlD7YUJPkFPw=
|
||||
=b498
|
||||
-----END PGP PUBLIC KEY BLOCK-----
|
@ -1,18 +0,0 @@
|
||||
Type Bits/KeyID Date User ID
|
||||
sec 888/A50283F1 2001/11/08 pgp2.6.3-test-key
|
||||
|
||||
-----BEGIN PGP SECRET KEY BLOCK-----
|
||||
Version: 2.6.3a
|
||||
|
||||
lQGdAzvqRosAAAEDeNMKLJMJQeGC2RG5Nec6R2mzC12N1wGLiYYJCsmSQd1Y8mht
|
||||
A2Sc+4k/q5+l6GHtfqUR/RTCIIudAZUzrQVIMhHDKF+5de9lsE5QxQS1u43QGVCb
|
||||
/9IYrOLOizYQ2pkBtD9LCrf7W2DccMEkpQKD8QAFEwADd0Kk5aeyFM3zbPgfikkE
|
||||
7iFg9h2LG3nARmA4wAnCZaQ3CS5zRHCdXOf5KLkm6xFza1yMat4iWx6ULvuuNpIc
|
||||
RmkHccyXYkRi3Hvacd5A9VCNw1UKtCdaCKgacsfplU0s1xYWGZd4J8Jg8boSfW5W
|
||||
gwG8Dc9R20HHno8uD2vfr5rg8ElWvbFyJI/j4eCVAd+NYAGNvB8I3VP38IIYcavh
|
||||
YYcGjrpxbGVRybsBvA9IJltpGaVulxwpeCp5NecCGgoAUsN4Ktf42Pg7HXDlQL6r
|
||||
Xs/YggMztj4NzEgBHXAOLShdKKhDAbEByVSKXZD9A8J+RejXBl6VbuJmD/5qOvph
|
||||
GAPKS3ahPDj8438HyD7yIDLYYVRKfxjWHLubc46Pgui0EXBncDIuNi4zLXRlc3Qt
|
||||
a2V5
|
||||
=l/aV
|
||||
-----END PGP SECRET KEY BLOCK-----
|
@ -1,27 +0,0 @@
|
||||
This is an encrypted version of plain-1 for the PGP test key
|
||||
0xCB879DE9 using 3DES.
|
||||
|
||||
-----BEGIN PGP MESSAGE-----
|
||||
Version: GnuPG v1.3.5-cvs (GNU/Linux)
|
||||
|
||||
hM4DW3oC8MuHnekQAv0U6qlDAA64QS/oZJErr1J77m5Dh7IFen3mAcwOxvL/POqS
|
||||
HQWTFcuFT4LH9asSWgRe6DebJGfscMjMqNPAkhEJtKQQ2jEesn2Bon6SMwah7vkD
|
||||
9Zap7WKHRlnB/Da1/xQC/ispXY7e5tuejnzoNSAOWFpBn354nvkKGaCfMRNuz3R2
|
||||
HljH+gXKRa00n2dPmvX9Mr8AI0Q+FoEI2/YW+6aUxmv8b0c2dP6HcL6HUu0Ro2Nl
|
||||
RJNPfYXP20EL/Xrv8LN0Ksnp3YKTWrz5gQKNr3DH5pn1PjFqAKz4JD6rQBpnlh1c
|
||||
03gLB1OAJWA6+/QNaEQV451GBZW3ul10R/6621/kk0Isdxn/htlD4Jl/jAvFdlQW
|
||||
ULBu1HorZZ5X/IMuMRFwSQkx+H8i0zq+LGr8+rLFVTRuXBrgpeTLWs/f35DDblPp
|
||||
jtPGSs1qql98PfOV1tAr16rGRLAAyNWEgi3yZWUGgq5dfFnRbJX1hrj9waQmq1g0
|
||||
mn1oB9Ig708xSZqcfFVFNpvIB7nmbFF/WaMnqfL3XmgTe8whKB/f/XYhg+W2d57h
|
||||
EmTcAlC1N6IHY8/7YqtnjitavTIUsi0hPldX0tvrjsaZ7ppSma2epRJhx47jIFjw
|
||||
wXOEByZE+K3pyTSN8KJxParDsqrTWFrL0t8az9W8lWG7YYsxUxk9cwRo5PyEko1M
|
||||
kAKrbDMb+02Iw35yeuxFY33dl7KqpaWy43ksX/ROxX4S0InQywaQejXyt5A1cJN1
|
||||
t+G0aKdRp40MDKtOkZfFGlUSFZIhB0dxKVfSKJE/SIeYZzROTuyCNe/2wwufxgpa
|
||||
uztUf5ipVnINupiztWGw5c5Wp40ptQ/0K4/35KrZhMoFGR9DtImAPpZocuiFdJDt
|
||||
uqqapxGfJ876S4hFjRAkHSNRsAySul9zFLnIJ+Smk5xsvQZK4yjDwZfSs9b7WPKg
|
||||
7NCxl5bF5dIbWRYdRBNjHQ4m3LyYmqKzQqALSYT54/9O35B7rb1fOB2SFIuME0QI
|
||||
5XQq9QsH/f5rW8U6Ixzw1582B8fO1TMRhCqMyXozmsBJoWdCIQTQiVNyrbgLi+ss
|
||||
wKiKq4AymLXFMSpI4TOCc+rKiAdMpLbNO8Ndox5hZEGz+mqg84cgC/rkJc/P03KR
|
||||
uo0+rb5eSfJw9t+uzBXDmFHynayj0CB8wW9iwXknpdlHDo1z
|
||||
=7Otr
|
||||
-----END PGP MESSAGE-----
|
@ -1,26 +0,0 @@
|
||||
-----BEGIN PGP MESSAGE-----
|
||||
Version: GnuPG v1.3.5-cvs (GNU/Linux)
|
||||
|
||||
hQEOA6urKKJHvid1EAQA0MchGc7vZsjUgxdII4lo/2jRDesMmLDN4U0uOgExvyhD
|
||||
u1OtQBJF8iHgNdDEf8/R3GWhRE94IpVwLqzKTqfVmyKIFd80/Qe4h37TUPpEf8Ex
|
||||
f7WaIBk/9OSDNKOkCwZ5OH9xGaorhBwYiTNJlEEGv5zcDte9ZoLO7WhWFfHp3b0E
|
||||
AJYk/tf3oV4sJSn8AbUa8UC2tAdpNM1Lx+UEuCtxevYRpWeDVDok7/xuaa/wcb39
|
||||
lKyhUV+FBUH++k59K4GVqykOz02hmFl97O+4bAldgP6cVTm0Gh7jwMcJANzhLW/O
|
||||
MR5birB+HPKOotMIfhggzxsAt6ESrviIlknkGqwKXWog0ukB/npOqQdu1GmvJqoC
|
||||
k6ElA6xZPY5HTF/JLKlLXFfIIKLeuyckKwGDkVNFE7JYPW+dfxcGH9z1KXaNNllY
|
||||
V4OKGQh3+gMaoJSY2X7PsmjC4fvi3g6rr360ATr5f82Mr8GPa3x21XLdIFZ04vTe
|
||||
yE3kwdcarkiT1QQLnOXk/yRBxJwiA5loL9crVdC2WyOV3B3DG33/yas8krw4BYWw
|
||||
DzAgxNtZR4MQXcj83WwoflMo43dYUq3Pk7ZnzKN04O8m9w0gxVxCpXu4ds9emMdJ
|
||||
WS4eNTPUOnzeWttkfYcd3SarK6COi9iBosFT2QF80FwDSlH3XdEo7rD1j6WJ5GeX
|
||||
RbHDvIm9g0xB23S7jmtfdqIHndvPKLmwW2B1VC1mbjcDUo6pyUb31GBd1zFVhT69
|
||||
ijhiEwBlr8uWxROdwJd/7IVIB/RYHLr5P3M8p08hdEdS1IMQbNEE4Y25fRdcc6g8
|
||||
fVEAExbG01K1EJhRLxoHzgnAkxDTV2HSwlqbFvKEzUfE+rMHApmSX2lfMvKgueYz
|
||||
JpA7nxuf79Wk17bjNvuVQwokhXpzw7FyPPdD7h4Z30LW0ozvSVgs2tigWCAysIKB
|
||||
3ZIolchqBoj0ddJgbPXrx09r1oCckEmdj1KtZsci9m+CFA8d22uxXBec0HkEHZpr
|
||||
EHlqEZfNTmqowoDtJ8KT+S8VPsALEyDnrqm3s4i44OwgvsPiKOST1xwk6lIJ5isu
|
||||
fO76RHTQ2jc8z7+sKyNffVugfjYVRj54/8Gj34QkrVo/42rlvg398tpbAbWuNq8w
|
||||
PM//M6eVD4IRDYEGrGOk7prd9mgdbWnOWpasirhr41kePu2vsrIUkJWHmOgdMQDH
|
||||
cSSzI8C5NpafROHAhMsUymcJ5dKksvPubh5IAdgtH+m6yDnNUJT8s6WV1f1RpSsQ
|
||||
L/n3dhti76l0XtfZ7aST8j46B1JPNDx8+r6Xl9IUbSU=
|
||||
=xK46
|
||||
-----END PGP MESSAGE-----
|
@ -1,28 +0,0 @@
|
||||
-----BEGIN PGP ARMORED FILE-----
|
||||
Version: GNUPG v0.3.4 (GNU/Linux)
|
||||
Comment: Get GNUPG from ftp://ftp.guug.de/pub/gcrypt/
|
||||
Comment: Use "gpgm --dearmor" for unpacking
|
||||
|
||||
PCEtLSBEaWVzIGlzdCBTZWl0ZSAzLCBkb3J0IGlzdCBrZWluZSBTZWl0ZW56YWhsIGFuZ2Vn
|
||||
ZWJlbiwKICAgICBvYmVuIHJlY2h0cyBpc3Qgd2llZGVyIGRlciBTdGVtcGVsIHZvbiBtZWlu
|
||||
ZW0gT3BhIHp1IGZpbmRlbiAtLT4KCjxzZWN0MT5OYW1lIDxxPkdyb98tQmFydGxvZmY8Lz4K
|
||||
CjxwPgpEZXIgTmFtZSA8cS9CYXJ0bG9mZi8gaXN0IHNjaHdlciB6dSBkZXV0ZW4uIE1hbiBo
|
||||
YXQgdmllbGUgTXV0bWHfdW5nZW4KYW5nZXN0ZWxsdCwgdm9uIGRlbmVuIG1hbiBhYmVyIGJp
|
||||
c2xhbmcga2VpbmUgZWluemlnZSBhbHMgdW5iZWRpbmd0CnJpY2h0aWcgZXJrbORyZW4ga2Fu
|
||||
bi4KPGZvbnRpbmZvIHJlbT0ibWl0IExlZXJ6ZWljaGVuIGdlc2NocmllYmVuIj5Vcmt1bmRs
|
||||
aWNoPC8+IHdpcmQgZGFzCkRvcmYgYmlzIHp1ciBSZWZvcm1hdGlvbiBzdGV0cyA8cS9CYXJ0
|
||||
b3JmLyAoYW5ubyAxMjUzKSB1bmQKPHEvQmFyZG9yZi8gKDEzMDYsIDEzMTgsIDEzMjksIDE0
|
||||
MjkpIGdlbmFubnQgdW5kIGRhc18gc293b2hsIEtsZWluLQp3aWUgR3Jv32JhcnRsb2ZmLiBF
|
||||
cnN0IDE1ODYgaW0gQmlzY2hvZnNzdGVpbmVyIEp1cmlzZGlrdGlvbmFsYnVjaApoZWnfdCB1
|
||||
bnNlciBEb3JmIDxxL0JhcnR0ZWxvZmYvIHVuZCBzbyBhdWNoIGluIGRlciDkbHRlc3RlbiBu
|
||||
b2NoCnZvcmhhbmRlbmVuIEtpcmNoZW5yZWNobnVuZyB2b20gSmFocmUgMTY1MS4gTkFjaCBk
|
||||
ZW0gSmFocmUgMTcwMCB3aXJkCmluIGRlbiBVcmt1bmRlbiBiZWdvbm5lbiwgZGVuIHZvbGxl
|
||||
biBOYW1lbiA8cS9Hcm/fLUJhcnRsb2ZmLyB1bmQKPHEvS2xlaW4tQmFydGxvZmYvIHp1IHNj
|
||||
aHJlaWJlbi4KLS0tLS0tLS0tLS0tLS0tLSBbd2VnZW4gZGFzaGVkIGVzY2FwZWQgdGV4dF0K
|
||||
PHA+Ck5pbW10IG1hbiBhbiwgZGHfIGRpZSB1cmt1bmRsaWNoZSwg5Gx0ZXN0ZSBCZXplaWNo
|
||||
bnVuZyBCYXJ0b3JmIGRpZQp1cnNwcvxuZ2xpY2hlIGlzdCB1bmQgbmljaHQgZGllIG11bmRh
|
||||
cnRsaWNoZSBCYXJ0bG9mZiwgc28ga/ZubnRlIGRlcgpOYW1lIGd1dCBnZWRldXRldCB3ZXJk
|
||||
ZW4gYWxzIERvcmYgYW4gZGVyIDxxL0JvcmRlLyBvZGVyIGFtIFJhbmRlCm9kZXIgYW4gZGVy
|
||||
IEdyZW56ZSBlbnR3ZWRlciBkZXMgV2FsZGVzCg==
|
||||
=m1k/
|
||||
-----END PGP ARMORED FILE-----
|
@ -1,31 +0,0 @@
|
||||
-----BEGIN PGP MESSAGE-----
|
||||
Version: GnuPG v1.3.5-cvs (GNU/Linux)
|
||||
|
||||
hQEOA6urKKJHvid1EAP/aYXFOkxPzbBB0SWtyX+yyvZso8i1WJS3pzrHNXcXQSQx
|
||||
xOAfmlCiuXYrjEzlyDAn7k7RLAhUB/ffI58HnbkQ7btWujrHig/V1tQ0j5igR85M
|
||||
3y2/msWu2c2pyeZnx29LzeoJ2aMVTbMObszlG+TNOuhCNn4unvbShrkFjNK5fi8E
|
||||
AIHiavE77ZPfcaUrXp6FJ6OuhbnJQ8y8CVpH++ddgU6xXK1vByMSsYqiOjfq08gV
|
||||
MzqT1eMVvKhSjl3R6Ktl7j+ErYM4KuIofIZsKc8M3JnoTSrLqWSEBq+DEiaSI58i
|
||||
SMJfzxfKA84bpJyLIjp4bjRIXveYoX8UjEnSNr3xuDIq0ukBoVe6Bx8lBActcwE+
|
||||
kE7EffSBHUmnm8cvwZan+Ms8t9p9aQEzBxV/LfEXZyk36lK35zCH188iJR+tt9zs
|
||||
rNubkRuOjq9jAcBtrvgjTTO91Ru7z4RCYeMfnX9AauJZFShBNYN46GTIwqMWE9vq
|
||||
B/IYFH9/L2nufcrDQ6u5WxJo0y2FoPqVS4RKEZ4FlKnlT2Op0X1k9w+1nWTtKwQx
|
||||
fPsB+YRSKmVbZOXDeKAIVEyGHgR1Hj6pbo/IeHSJ2DJt5OFu6eLQYjxYjM7BPjPD
|
||||
Gn+lTUvqw5ykYpCcnvpEx25+qHh5HI11Hi0sLKzvB92hhsQ7+lU2D+iAzsMJKdwE
|
||||
u2bCnrZokzZwDBy6NISQ+hoc6NPPezQM4FLN0BB752fa9DYMQo5nEGfPUM7fv51A
|
||||
nUdGOmaDVWY54GQxiYzl0JAT41sQSYlVHcWBCGNAm064y+tsHVjDYcf5uze/3Iuw
|
||||
m/IbRGLBT7x+j2OqMX30yXoeHCg0/M/2c6vIzhdHEsJjTbTr+M4bMii/mB5kSo/7
|
||||
x5R14Lr0mwnPNDFHG2egqd5uL8985+5BENm7q0pQHKGM5NxkjVSWCpzRgKcSEq5A
|
||||
x4Q2HbhEJNP6ZonnZkDmGM52Eq62eaR7t8+k9px35osfiTiClmVrjsTgl5Kvatk0
|
||||
oL1aYEwp8OtavoSwidUTk+Xb+cEE09P5bnCFs5Js0e5wdo+/izJ6iBuF+PndTh4i
|
||||
4ppFmt8/GZ63MKBJu4CZE7QJMVAcmmCrsGRONP2JVgmyaBjrIl5xk9FPXQVY0AJx
|
||||
gl3/jO/QFHYs+dlrQ3aqg8Mm0eZyLmZEYjoNibD8PW0keYiVfTF7EGl4jS2sAboc
|
||||
AOzbuABa+30vIjJRWeW5UdTcLyNK7B2qWk6dqpRn9ps3cwCWUiTIcIRgot4PY+3M
|
||||
8BL4smyZIP1Fmz/woL7gSVIaJHMExHjYPyRlfo+6Vfy3hh3zdiB9e5xA8QRFKgUb
|
||||
Px5ShU5bBykfvFBJjgKU1XLBKqdklaudf3+v8F3LPIyuO6vTYzOIU9UKAHy9CrA2
|
||||
kAZ8kgHBTtAjmKuJjASBCZHPepq0G9SaRDQI5g4DXx0LXPX3y5xkwVI6kd0QmsMF
|
||||
UU4ij/xjzIPN/AxBgQI8HKk56FnaX0JKoHm7mqWa+1TzbuvJjio4J/IN9XXzVqb1
|
||||
YL+mkx607hdW9oJltXLO5eio0pb12v/0YXAQlsrlJJNPCUW5hYFv/vH1rHzR98xx
|
||||
nx4PXElm8VUuhKDxdVi9Ipo8fL9Amu3PwYonzOck3R2W4wwlmcopVQQ=
|
||||
=Ng8B
|
||||
-----END PGP MESSAGE-----
|
@ -1,36 +0,0 @@
|
||||
-----BEGIN PGP ARMORED FILE-----
|
||||
Version: GNUPG v0.3.4 (GNU/Linux)
|
||||
Comment: Get GNUPG from ftp://ftp.guug.de/pub/gcrypt/
|
||||
Comment: Use "gpgm --dearmor" for unpacking
|
||||
|
||||
Cgo8c2VjdD5Wb3J3b3J0CjxwPgpEZXIgV2VydCBlaW5lciBPcnRzY2hyb25payBpc3Qgb2Zm
|
||||
ZW5iYXIgdW5kIGJlZGFyZiBrZWluZXIgRXL2cnRlcnVuZy4KTWl0IEF1c2JydWNoIGRlcyBX
|
||||
ZWx0a3JpZWdlc18sIGlubWl0dGVuIGRlciBnZXdhbHRpZ2VuIEdlc2NoZWhuaXNzZSwgZvxo
|
||||
bHRlCmRlciBLbGVydXNfIHVuc2VyZXNfIEVpY2hzX2ZlbGRlc18gZGFzXyBtZWhyIHdpZSBm
|
||||
cvxoZXIgdW5kIHNvCmVyc3Rhcmt0ZSBkYXNfIFN0cmViZW4sIGVpbmUgc29sY2hlIE9ydHNf
|
||||
Z2VzY2hpY2h0ZSB6dSBzY2FoZmZlbiwgdW0KdW5zZXJlbiBOYWNoa29tbWVuIHp1IGJlcmlj
|
||||
aHRlbiwgd2FzXyBhdWNoIGRpZSBrbGVpbnN0ZW4gRPZyZmVyIGluCmRlciBncm/fZW4gWmVp
|
||||
dCBnZWxlaXN0ZXQsIGVybGVidCB1bmQgZXJsaXR0ZW4gaGFiZW4uCjxwPgpVbmQgc28gYmVn
|
||||
YW5uIGF1Y2ggaWNoIGltIERlemVtYmVyIDE5MTQsIGRlbiA/Pz8/Pz8/Pz8KU3RvZmYsIHdv
|
||||
IGltbWVyIGljaCBpaG4gYXVjaCBudXIgc28gc3DkcmxpY2ggZmluZGVuIGtvbm50ZSwgenUK
|
||||
c2FtbWVsbiwgaWNoIGJlZnJhZ3RlIHp1buRjaHN0IGVtc2lnIGRpZSDkbHRlc3RlbiBMZXV0
|
||||
ZSwKZHVyY2hmb3JzY2h0ZSBzb2Rhbm4gZGFzIGdhbnplIFBmYXJyYXJjaGl2LCBkYXMgU2No
|
||||
dWx6ZW5hcmNoaXYKYmVpZGVyIFBmYXJyZPZyZmVyLCBkYXMgS29tbWlzc2FyaWF0c19hcmNo
|
||||
aXYgenUgSGVpbGlnZW5zdGFkdCwKZW5kbGljaCBhdWNoIDE5MTYgZGFzIFN0YWF0c19hcmNo
|
||||
aXYgenUgTWFnZGVidXJnLiBTZWxic3R2ZXJzdORuZGxpY2gKYXJiZWl0ZXRlIGljaCBhdWNo
|
||||
IGRpZSBlaW5zY2hs5GdpZ2UgTGl0ZXJhdHVyIGR1cmNoLiBHYXIgdmllbGUgWmVpdAp1bmQg
|
||||
TfxoZSBoYXQgZXNfIGdla29zdGV0IHVtIG5hY2ggbWVociBhbHMgOCBKYWhyZW4gZGllIE9y
|
||||
dHNjaHJvbmlrIHZvbgpHcm/fYmFydGxvZmYgdW5kIHZvbSBGaWxpYWxkb3JmIFdpbGJpY2gg
|
||||
Z2Vzb25kZXJ0IHp1IHNjaGFmZmVuLgo8cCB2c3BhY2U9IjJleCI+CjxiZj5Hcm/fYmFydGxv
|
||||
ZmYsPC8+IGRlbiAyMy4gTeRyeiAxOTIzLgo8cCB2c3BhY2U9IjNleCIgYWxpZ249cmlnaHQ+
|
||||
CjxiZi9OaWtvbGF1cyBH9nJpbmcsLyBQZmFycmVyLgo8L3A+Cgo8IS0tIEhpZXIgZm9sZ3Qg
|
||||
ZWluIFN0ZW1wZWwgdm9uIG1laW5lbSBPcGE6CgkgIFJ1ZC4gS29jaAogICAgIEdyb99iYXJ0
|
||||
bG9mZi9FaWNoc2ZlbGQKCUFuZ2VyIDE2MQotLT4KPCEtLSBGSVhNRTogaGllciBrb21tdCBl
|
||||
aW5lbiBaaWVybGluaWUgLS0+Cgo8cCB2c3BhY2U9ZmlsbD4gPCEtLSBEZXIgUmVzdCBrYW0g
|
||||
YW0gRW5kZSBkZXIgU2VpdGUgLS0+CjxwIGFsaWduPWNlbnRlcj4gTGl0ZXJhdHVyOiA8L3A+
|
||||
CjEpIEpvaC4gV29sZjogUG9saXRpc2NoZSBHZXNjaGljaHRlIGRlcyBFaWNoc2YuIEf2dHQu
|
||||
IDE3OTIgdW5kCkz2ZmZsZXIgMTkyMS4gMikgSy4gR2VzY2hpY2h0ZSwgV29sZiAxODE2IEf2
|
||||
dHQuICAzKSBLbmllYjogR2VzY2guCmRlciBSZWYuIHUuIEdlZ2VucmVmPz8/Cgo8IS0tIEZJ
|
||||
WE1FOiBEZXIgUmVzdCBmZWhsdCBub2NoIC0tPgoKCgoKCgoKCjwvc2VjdD4K
|
||||
=9nnj
|
||||
-----END PGP ARMORED FILE-----
|
@ -1,13 +0,0 @@
|
||||
-----BEGIN PGP MESSAGE-----
|
||||
Version: GnuPG v1.3.5-cvs (GNU/Linux)
|
||||
|
||||
hQEOA6urKKJHvid1EAQAreXx68NPUPpiNhqRyM//Y97N8hX5iAWq3WxXTa8D6Hy9
|
||||
81Jy2wI4IeDhHIoWuXMIX2oVL//V1+LyLkrF/tutBVvqct0TUDUWqb4Ydpfk2l5j
|
||||
FfSybWW1fS4D1e0KVB3Lfj2Y4cCoT/+zyq7jUKQE++qNefPBzeaRWY4qeI6xXF8E
|
||||
AMj01HPe0ZwIBWqiIYv91Q7rGzEZm0ROPilgSQjUvCdsNQGhZpFGTl6uMSU0lmp8
|
||||
SD2EKv3xGeo2nMPy/Xp4JoYAMW+fjJh+wM6uT84nJgCVaeWyR7HAfF1U4rzqz7DF
|
||||
amPozuwuZiyjoo/wB1irZSl90t5Oa69oMesZtGMvwBN10mMBM0TotT4gjgviv5uY
|
||||
kLjD7DM79xy0drptNypmcVcjnDunM6bSEhTyq/fahdaULTYcwSOTXVMyesNpmLCb
|
||||
ziayleyuSaXPxIqWTgSfkab/W2FGWZvbexYaSaWXmDqsyzs81o0=
|
||||
=JDKF
|
||||
-----END PGP MESSAGE-----
|
@ -1,10 +0,0 @@
|
||||
Stored by G10, because diff/patch have problems with
|
||||
files not having a trailing LF - and this one has none.
|
||||
|
||||
-----BEGIN PGP ARMORED FILE-----
|
||||
Version: G10 v0.2.6a (Linux)
|
||||
Comment: This is an alpha version!
|
||||
|
||||
RGllcyBpc3QgZWluZSBlaW5mYWNoZSBaZWlsZSBvaG5lIExGIGFtIEVuZGUu
|
||||
=ZQ6m
|
||||
-----END PGP ARMORED FILE-----
|
@ -1,566 +0,0 @@
|
||||
26 demo keys:
|
||||
|
||||
pub 1024D/68697734 1999-03-08 Alpha Test (demo key) <alpha@example.net>
|
||||
uid Alice (demo key)
|
||||
uid Alfa Test (demo key) <alfa@example.net>
|
||||
sub 1024g/46A871F8 1999-03-08
|
||||
pub 1024D/1AFDAB6C 1999-03-08 Charlie Test (demo key) <charlie@example.net>
|
||||
sub 1024g/BC43DA60 1999-03-08
|
||||
pub 1024D/FAEF6D1B 1999-03-08 Echo Test (demo key) <echo@example.net>
|
||||
uid Eve (demo key)
|
||||
uid Echelon (demo key)
|
||||
sub 1024g/7272144D 1999-03-08
|
||||
pub 1024D/8FC282E6 1999-03-08 Golf Test (demo key) <golf@example.net>
|
||||
sub 1024g/9DCAD354 1999-03-08
|
||||
pub 1024D/04259677 1999-03-08 India Test (demo key) <india@example.net>
|
||||
sub 1024g/61F76C73 1999-03-08
|
||||
pub 1024D/43C2D0C7 1999-03-08 Kilo Test (demo key) <kilo@example.net>
|
||||
sub 1024g/9AF64D02 1999-03-08
|
||||
pub 1024D/A9E3B0B2 1999-03-08 Bravo Test (demo key) <bravo@example.net>
|
||||
uid Bob (demo key)
|
||||
sub 1024g/E29BA37F 1999-03-08
|
||||
pub 1024D/EB9DC9E6 1999-03-08 Delta Test (demo key) <delta@example.net>
|
||||
sub 1024g/B0C45424 1999-03-08
|
||||
pub 1024D/7372E243 1999-03-08 Foxtrot Test (demo key) <foxtrot@example.net>
|
||||
sub 1024g/EE45198E 1999-03-08
|
||||
pub 1024D/34C6E3F1 1999-03-08 Hotel Test (demo key) <hotel@example.net>
|
||||
sub 1024g/D622AD0A 1999-03-08
|
||||
pub 1024D/D2699313 1999-03-08 Juliet Test (demo key) <juliet@example.net>
|
||||
sub 1024g/35F8F136 1999-03-08
|
||||
pub 1024D/B79103F8 1999-03-08 Lima Test (demo key) <lima@example.net>
|
||||
sub 1024g/FE56350C 1999-03-08
|
||||
pub 1024D/BE5CF886 1999-03-08 Mike Test (demo key) <mike@example.net>
|
||||
uid Mallory (demo key)
|
||||
sub 1024g/4F31EAE8 1999-03-08
|
||||
pub 1024D/30CEC684 1999-03-08 November Test (demo key) <november@example.net>
|
||||
sub 1024g/8B70E472 1999-03-08
|
||||
pub 1024D/6D9732AC 1999-03-08 Oscar Test (demo key) <oscar@example.net>
|
||||
sub 1024g/2681619F 1999-03-08
|
||||
pub 1024D/3FF13206 1999-03-08 Papa test (demo key) <papa@example.net>
|
||||
sub 1024g/63330D9C 1999-03-08
|
||||
pub 1024D/3C661C84 1999-03-08 Quebec Test (demo key) <quebec@example.net>
|
||||
sub 1024g/A029ACF4 1999-03-08
|
||||
pub 1024D/777FBED3 1999-03-08 Romeo Test (demo key) <romeo@example.net>
|
||||
sub 1024g/11D102EA 1999-03-08
|
||||
pub 1024D/A3AE3EA1 1999-03-08 Sierra Test (demo key) <sierra@example.net>
|
||||
sub 1024g/0F1B50B4 1999-03-08
|
||||
pub 1024D/85A81F38 1999-03-08 Tango Test (demo key) <tango@example.net>
|
||||
sub 1024g/101C0402 1999-03-08
|
||||
pub 1024D/653244D6 1999-03-08 Uniform Test (demo key) <uniform@example.net>
|
||||
sub 1024g/5522BDB9 1999-03-08
|
||||
pub 1024D/61F04784 1999-03-08 Victor Test (demo key) <victor@example.org>
|
||||
sub 1024g/07287134 1999-03-08
|
||||
pub 1024D/EC67DBDE 1999-03-08 Whisky Test (demo key) <whisky@example.net>
|
||||
sub 1024g/FD6E27F6 1999-03-08
|
||||
pub 1024D/567FB34A 1999-03-08 XRay Test (demo key) <xray@example.net>
|
||||
sub 1024g/41E408BE 1999-03-08
|
||||
pub 1024D/4B11B25F 1999-03-08 Yankee Test (demo key) <yankee@example.net>
|
||||
sub 1024g/F7B080AD 1999-03-08
|
||||
pub 1024D/54ACD246 1999-03-08 Zulu Test (demo key) <zulu@example.net>
|
||||
sub 1024g/A172C881 1999-03-08
|
||||
|
||||
-----BEGIN PGP PUBLIC KEY BLOCK-----
|
||||
Version: GnuPG v0.9.3 (GNU/Linux)
|
||||
Comment: For info see http://www.gnupg.org
|
||||
|
||||
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
|
||||
=1N8S
|
||||
-----END PGP PUBLIC KEY BLOCK-----
|