Page MenuHome GnuPG

No OneTemporary

This file is larger than 256 KB, so syntax highlighting was skipped.
This document is not UTF8. It was detected as ISO-8859-1 (Latin 1) and converted to UTF8 for display.
diff --git a/ChangeLog b/ChangeLog
index 7b14b7944..86bd01bff 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,476 +1,481 @@
+2004-08-16 Werner Koch <wk@g10code.de>
+
+ * configure.ac: Build Makefile for tests/pkits. New option
+ --with-pkits-tests.
+
2004-08-05 Werner Koch <wk@g10code.de>
* configure.ac: Changed tests for libusb to also suuport the
stable version 0.1.x.
2004-07-22 Werner Koch <wk@g10code.de>
Released 1.9.10.
* configure.ac: Define AM conditional HAVE_OPENSC.
2004-07-21 Werner Koch <wk@g10code.de>
* configure.ac: Don't set DIE to no after it might has been set to
yes.
2004-07-20 Werner Koch <wk@g10code.de>
* Makefile.am (sm): Build kbx only if gpgsm is to be build.
2004-07-20 Werner Koch <wk@gnupg.org>
* configure.ac: New option --enable-agent-only.
2004-06-08 Werner Koch <wk@gnupg.org>
Released 1.9.9.
2004-06-06 Werner Koch <wk@gnupg.org>
* configure.ac: Require libksba 0.9.7.
2004-04-29 Werner Koch <wk@gnupg.org>
Released 1.9.8.
2004-04-20 Werner Koch <wk@gnupg.org>
* configure.ac: Remove the fopencookie test. We don't need the
dummy function because we conditionally use fopencookie,
fpencookie or a replacement at place.
2004-04-02 Thomas Schwinge <schwinge@nic-nac-project.de>
* autogen.sh: Added ACLOCAL_FLAGS.
2004-04-06 Werner Koch <wk@gnupg.org>
Released 1.9.7.
* configure.ac: Require libgcrypt 1.1.94.
Introduce PACKAGE_GT and set it to gnupg2.
2004-03-23 Werner Koch <wk@gnupg.org>
* configure.ac: Define SAFE_VERSION_DASH and SAFE_VERSION_DOT.
2004-03-09 Werner Koch <wk@gnupg.org>
* configure.ac (NEED_GPG_ERROR_VERSION): Set to 0.7.
2004-03-06 Werner Koch <wk@gnupg.org>
Released 1.9.6.
* configure.ac: Check the Libgcrypt API.
2004-02-25 Werner Koch <wk@gnupg.org>
* configure.ac: New option --disable-threads to inhibit
unintentional builds without Pth.
2004-02-21 Werner Koch <wk@gnupg.org>
Released 1.9.5.
2004-02-20 Werner Koch <wk@gnupg.org>
* configure.ac: Fixed URLs in the notice messages.
2004-02-18 Werner Koch <wk@gnupg.org>
* acinclude.m4: Removed macros to detect gpg-error, libgcrypt,
libassuan and ksba as they are now distributed in m4/.
2004-02-13 Werner Koch <wk@gnupg.org>
* configure.ac: Require libksba 0.9.4 and libgcrypt 1.1.92.
2004-02-12 Werner Koch <wk@gnupg.org>
* autogen.sh: Removed cruft from debugging.
* am/cmacros.am: New.
2004-02-11 Werner Koch <wk@gnupg.org>
* configure.ac: Removed the need for g10defs.h. Reworked the
--with-foo-pgm stuff.
* autogen.sh (check_version): Removed bashism and simplified.
* acinclude.m4 (AM_PATH_OPENSC): Kludge to avoid error output for
a bad opensc-config.
2004-01-30 Werner Koch <wk@gnupg.org>
Released 1.9.4.
* configure.ac: Require libksba 0.9.3 due to another bug fix there.
2004-01-29 Werner Koch <wk@gnupg.org>
* README: Updated.
* configure.ac: Require libksba 0.9.2 due to bug fixes.
2004-01-24 Werner Koch <wk@gnupg.org>
* configure.ac: Now requires libassuan 0.6.3.
2003-12-23 Werner Koch <wk@gnupg.org>
Released 1.9.3.
* README-alpha: Removed.
* configure.ac, Makefile.am: Add the tests and tools directories.
2003-12-19 Werner Koch <wk@gnupg.org>
* configure.ac: Now require libgcrypt 1.1.91 to help testing the
latest libgcrypt changes. Requires libksab 0.9.1.
2003-12-17 Werner Koch <wk@gnupg.org>
* configure.ac: Requires now libassuan 0.6.2.
(CFLAGS): Add --Wformat-noliteral in gcc mode.
2003-12-16 Werner Koch <wk@gnupg.org>
* configure.ac: Check for funopen and fopencookie as part of the
jnlib checks.
2003-12-09 Werner Koch <wk@gnupg.org>
* configure.ac: Add a min_automake_version.
* README.CVS: New.
* autogen.sh: Revamped except for the --build-w32 hack.
* Makefile.am: Add README.CVS
2003-11-17 Werner Koch <wk@gnupg.org>
Release 1.9.2.
* configure.ac: Requires now libassuan 0.6.1.
2003-10-31 Werner Koch <wk@gnupg.org>
* configure.ac (NEED_KSBA_VERSION): Set to 0.9.0 due the changed
time interface.
2003-10-21 Werner Koch <wk@gnupg.org>
* configure.ac (PRINTABLE_OS_NAME): Remove special case for The
Hurd; Robert Millan reported that the uname test is now
sufficient.
2003-10-01 Werner Koch <wk@gnupg.org>
* configure.ac (AH_BOTTOM): Define GNUPG_MAJOR_VERSION.
2003-09-23 Werner Koch <wk@gnupg.org>
Merged most of David Shaw's changes in 1.3 since 2003-06-03.
* configure.ac: Drop all TIGER/192 support.
(uint64_t): Check for UINT64_C to go along with uint64_t.
(getaddrinfo): Check for it.
(sigset_t): Check for sigset_t and struct sigaction. This is for
Forte c89 on Solaris which seems to define only the function call
half of the two pairs by default.
(W32LIBS): Include wsock32 in W32LIBS. This is different from
NETLIBS so we don't need to force other platforms to pull in the
netlibs when they aren't actually needed.
2003-09-06 Werner Koch <wk@gnupg.org>
Released 1.9.1.
* configure.ac: Require newer versions of some libraries.
2003-09-02 Werner Koch <wk@gnupg.org>
* configure.ac (HAVE_LIBUSB): Added a simple test for libusb.
2003-08-19 Marcus Brinkmann <marcus@g10code.de>
* configure.ac (AM_PATH_GPG_ERROR): Add missing comma in
invocation.
2003-08-06 Werner Koch <wk@gnupg.org>
* configure.ac: Check for libgpg-error. Print infos about missing
libraries more nicely.
* acinclude.m4 (AM_PATH_GPG_ERROR): Added.
2003-08-05 Werner Koch <wk@gnupg.org>
Released 1.9.0.
* configure.ac (GNUPG_DEFAULT_HONMEDIR): Changed back to ~/.gnupg.
2003-07-31 Werner Koch <wk@gnupg.org>
* Makefile.am (DISTCLEANFILES): Add g10defs.h
2003-06-18 Werner Koch <wk@gnupg.org>
* configure.ac (GNUPG_DEFAULT_HOMEDIR): Changed temporary to
.gnupg2 to avoid accidential use with production keys.
2003-06-11 Werner Koch <wk@gnupg.org>
* configure.ac: Merged all stuff from current 1.3 version in.
* acinclude.m4: Merged required macros from current 1.2 version in.
2003-06-04 Werner Koch <wk@gnupg.org>
* configure.ac, Makefile.am: Enable building of gpg.
2003-04-29 Werner Koch <wk@gnupg.org>
* configure.ac: Build a limited version of scdaemon if libopensc
is not available.
* configure.ac (ALL_LINUGAS): Removed.
* Makefile.am (ACLOCAL_AMFLAGS): New.
* configure.ac (AM_GNU_GETTEXT_VERSION): New. Set to 0.11.5.
2003-04-29 gettextize <bug-gnu-gettext@gnu.org>
* Makefile.am (SUBDIRS): Add m4.
(ACLOCAL_AMFLAGS): New variable.
(EXTRA_DIST): Add scripts/config.rpath.
* configure.ac (AC_CONFIG_FILES): Add m4/Makefile.
2003-04-29 Werner Koch <wk@gnupg.org>
* assuan/ : Removed. We now use libassuan.
* Makefile.am (SUBDIRS): Removed assuan
* configure.ac: Check for libassuan.
2003-01-09 Werner Koch <wk@gnupg.org>
* configure.ac (GNUPG_PROTECT_TOOL): New option --with-protect-tool.
(NEED_KSBA_VERSION): Does now require 0.4.6.
* README: Noted where to find gpg-protect-tool.
2002-10-31 Neal H. Walfield <neal@g10code.de>
* configure.ac: Check for flockfile and funlockfile. Check for
isascii and putc_unlocked replacing them if not found.
* configure.ac (PTH_LIBS): If pth is found, add the output of
`$PTH_CONFIG --ldflags`, not just `$PTH_CONFIG --libs`.
2002-10-19 Werner Koch <wk@gnupg.org>
* configure.ac: Bumped version number to 1.9.0-cvs.
NewPG (Aegypten project) to GnuPG merge.
2002-09-20 Werner Koch <wk@gnupg.org>
Released 0.9.2.
2002-09-05 Neal H. Walfield <neal@g10code.de>
* configure.ac: Check for makeinfo.
2002-09-03 Neal H. Walfield <neal@g10code.de>
* autogen.sh (have_version): New function. Generalize and
simplify logic for finding and determining the versions of GNU
programs. Use it.
2002-08-23 Werner Koch <wk@gnupg.org>
Released 0.9.1.
* acinclude.m4 (AM_PATH_LIBGCRYPT): Updated from Libgcrypt.
(AM_PATH_OPENSC): Strip non-digits from the micro version.
2002-08-21 Werner Koch <wk@gnupg.org>
Released 0.9.0.
* configure.ac: Changed the default homedir to .gnupg.
* README-alpha: Removed.
2002-08-19 Werner Koch <wk@gnupg.org>
* acinclude.m4: Removed -lpcsclite from KSBA_LIBS; copy+paste bug.
2002-08-13 Werner Koch <wk@gnupg.org>
* acinclude.m4 (AM_PATH_OPENSC, AM_PATH_KSBA): New.
* configure.ac: Use them.
2002-08-10 Werner Koch <wk@gnupg.org>
Released 0.3.10.
* configure.ac (NEED_LIBKSBA_VERSION): Require 0.4.4. Add support
for gettext.
2002-07-22 Werner Koch <wk@gnupg.org>
* configure.ac: Check for ftello and provide a replacement.
2002-07-01 Werner Koch <wk@gnupg.org>
Released 0.3.9.
* README: Short note on how to export in pkcs-12 format.
2002-06-29 Werner Koch <wk@gnupg.org>
* configure.ac: Define --with options to set the default location
of the agent, scdaemon, pinentry and dirmngr.
2002-06-27 Werner Koch <wk@gnupg.org>
* README: Short blurb on how to import a PKCS-12 file.
* configure.ac (AH_BOTTOM): New to define some constants.
2002-06-25 Werner Koch <wk@gnupg.org>
Released 0.3.8.
* configure.ac (NEED_LIBGCRYPT_VERSION): Set to 1.1.8.
2002-06-12 Werner Koch <wk@gnupg.org>
* configure.ac (NEED_LIBKSBA_VERSION): We need 0.4.3 now.
2002-06-04 Werner Koch <wk@gnupg.org>
Released 0.3.7.
2002-05-21 Werner Koch <wk@gnupg.org>
* configure.ac: We now require libgcrypt 1.1.7 and libksba 0.4.2.
2002-05-14 Werner Koch <wk@gnupg.org>
* doc/: New
* configure.ac, Makefile.am: Added doc/
2002-05-03 Werner Koch <wk@gnupg.org>
Released 0.3.6.
2002-04-25 Werner Koch <wk@gnupg.org>
* configure.ac: Check for setlocale.
2002-04-24 Marcus Brinkmann <marcus@g10code.de>
* configure.ac: Check for locale.h.
2002-04-15 Werner Koch <wk@gnupg.org>
Released 0.3.5.
* NEWS: Started to describe release notes.
* configure.ac (NEED_LIBKSBA_VERSION, NEED_LIBGCRYPT_VERSION): Defined
2002-04-01 Werner Koch <wk@gnupg.org>
Released 0.3.4.
2002-03-18 Werner Koch <wk@gnupg.org>
Released 0.3.3.
2002-03-08 Werner Koch <wk@gnupg.org>
* README: Add some explanation on how to specify a user ID.
2002-03-06 Werner Koch <wk@gnupg.org>
Released 0.3.2.
2002-03-04 Werner Koch <wk@gnupg.org>
Released 0.3.1.
* README: Explained some options and files.
2002-02-14 Werner Koch <wk@gnupg.org>
* configure.ac: Fixed status messages related to presence of Pth.
2002-02-13 Werner Koch <wk@gnupg.org>
* acinclude.m4 (GNUPG_SYS_SO_PEERCRED): New.
* configure.ac: use it.
2002-02-12 Werner Koch <wk@gnupg.org>
* configure.ac: Check for PTH. Provide replacement fucntions for
apsrintf and fopencookie.
* acinclude.m4 (GNUPG_PTH_VERSION_CHECK): New.
2002-02-07 Werner Koch <wk@gnupg.org>
Released 0.3.0.
* configure.ac: Require libgcrypt 1.1.6.
2002-02-01 Marcus Brinkmann <marcus@g10code.de>
* configure.ac (KSBA_CONFIG): Remove superfluous x in front of
variable.
2002-01-26 Werner Koch <wk@gnupg.org>
* configure.ac: Add options to disable the build of some programs
and print a configure status at the end.
* acinclude.m4 (GNUPG_BUILD_PROGRAM): New.
* scd/ : New. Added to Makefile and configure.
* configure.ac: Check for libopensc
* Makefile.am: Build scd only when libopensc is available
2002-01-23 Werner Koch <wk@gnupg.org>
* configure.ac (mkdtemp): See whether we have to provide a
replacement.
2001-12-18 Werner Koch <wk@gnupg.org>
Released 0.0.0.
2001-12-17 Werner Koch <wk@gnupg.org>
* acinclude.m4: Add AM_PATH_LIBGCRYPT macro.
* configure.ac: and use it here. Figure out the location of libksba
2001-12-15 Werner Koch <wk@gnupg.org>
* configure.ac (missing_dir): Bail out if asprintf and fopencookie
are not available.
2001-12-04 Werner Koch <wk@gnupg.org>
* configure.ac (HAVE_JNLIB_LOGGING): always define it.
Copyright 2001, 2002, 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.
diff --git a/NEWS b/NEWS
index df35b570e..2fbf6475e 100644
--- a/NEWS
+++ b/NEWS
@@ -1,182 +1,185 @@
Noteworthy changes in version 1.9.11
-------------------------------------------------
+ * When using --import along with --with-validation, the imported
+ certificates are validated and only imported if they are fully
+ valid.
Noteworthy changes in version 1.9.10 (2004-07-22)
-------------------------------------------------
* Fixed a serious bug in the checking of trusted root certificates.
* New configure option --enable-agent-pnly allows to build and
install just the agent.
* Fixed a problem with the log file handling.
Noteworthy changes in version 1.9.9 (2004-06-08)
------------------------------------------------
* [gpg-agent] The new option --allow-mark-trusted is now required to
allow gpg-agent to add a key to the trustlist.txt after user
confirmation.
* Creating PKCS#10 requests does now honor the key usage.
Noteworthy changes in version 1.9.8 (2004-04-29)
------------------------------------------------
* [scdaemon] Overhauled the internal CCID driver.
* [scdaemon] Status files named ~/.gnupg/reader_<n>.status are now
written when using the internal CCID driver.
* [gpgsm] New commands --dump-{,secret,external}-keys to show a very
detailed view of the certificates.
* The keybox gets now compressed after 3 hours and ephemeral
stored certificates are deleted after about a day.
* [gpg] Usability fixes for --card-edit. Note, that this has already
been ported back to gnupg-1.3
Noteworthy changes in version 1.9.7 (2004-04-06)
------------------------------------------------
* Instrumented the modules for gpgconf.
* Added support for DINSIG card applications.
* Include the smimeCapabilities attribute with signed messages.
* Now uses the gettext domain "gnupg2" to avoid conflicts with gnupg
versions < 1.9.
Noteworthy changes in version 1.9.6 (2004-03-06)
------------------------------------------------
* Code cleanups and bug fixes.
Noteworthy changes in version 1.9.5 (2004-02-21)
------------------------------------------------
* gpg-protect-tool gets now installed into libexec as it ought to be.
Cleaned up the build system to better comply with the coding
standards.
* [gpgsm] The --import command is now able to autodetect pkcs#12
files and import secret and private keys from this file format.
A new command --export-secret-key-p12 is provided to allow
exporting of secret keys in PKCS\#12 format.
* [gpgsm] The pinentry will now present a description of the key for
whom the passphrase is requested.
* [gpgsm] New option --with-validation to check the validity of key
while listing it.
* New option --debug-level={none,basic,advanced,expert,guru} to map
the debug flags to sensitive levels on a per program base.
Noteworthy changes in version 1.9.4 (2004-01-30)
------------------------------------------------
* Added support for the Telesec NKS 2.0 card application.
* Added simple tool addgnupghome to create .gnupg directories from
/etc/skel/.gnupg.
* Various minor bug fixes and cleanups; mainly gpgsm and gpg-agent
related.
Noteworthy changes in version 1.9.3 (2003-12-23)
------------------------------------------------
* New gpgsm options --{enable,disable}-ocsp to validate keys using
OCSP. This option requires a not yet released DirMngr version.
Default is disabled.
* The --log-file option may now be used to print logs to a socket.
Prefix the socket name with "socket://" to enable this. This does
not work on all systems and falls back to stderr if there is a
problem with the socket.
* The options --encrypt-to and --no-encrypt-to now work the same in
gpgsm as in gpg. Note, they are also used in server mode.
* Duplicated recipients are now silently removed in gpgsm.
Noteworthy changes in version 1.9.2 (2003-11-17)
------------------------------------------------
* On card key generation is no longer done using the --gen-key
command but from the menu provided by the new --card-edit command.
* PINs are now properly cached and there are only 2 PINs visible.
The 3rd PIN (CHV2) is internally syncronized with the regular PIN.
* All kind of other internal stuff.
Noteworthy changes in version 1.9.1 (2003-09-06)
------------------------------------------------
* Support for OpenSC is back. scdaemon supports a --disable-opensc to
disable OpenSC use at runtime, so that PC/SC or ct-API can still be
used directly.
* Rudimentary support for the SCR335 smartcard reader using an
internal driver. Requires current libusb from CVS.
* Bug fixes.
Noteworthy changes in version 1.9.0 (2003-08-05)
------------------------------------------------
====== PLEASE SEE README-alpha =======
* gpg has been renamed to gpg2 and gpgv to gpgv2. This is a
temporary change to allow co-existing with stable gpg versions.
* ~/.gnupg/gpg.conf-1.9.0 is fist tried as config file before the
usual gpg.conf.
* Removed the -k, -kv and -kvv commands. -k is now an alias to
--list-keys. New command -K as alias for --list-secret-keys.
* Removed --run-as-shm-coprocess feature.
* gpg does now also use libgcrypt, libgpg-error is required.
* New gpgsm commands --call-dirmngr and --call-protect-tool.
* Changing a passphrase is now possible using "gpgsm --passwd"
* The content-type attribute is now recognized and created.
* The agent does now reread certain options on receiving a HUP.
* The pinentry is now forked for each request so that clients with
different environments are supported. When running in daemon mode
and --keep-display is not used the DISPLAY variable is ignored.
* Merged stuff from the newpg branch and started this new
development branch.
Copyright 2002, 2003 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.
diff --git a/TODO b/TODO
index 6e5c8cfb8..ce0db37aa 100644
--- a/TODO
+++ b/TODO
@@ -1,103 +1,106 @@
-*- outline -*-
* src/base64
** Make parsing more robust
Currently we don't cope with overlong lines in the best way.
* 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).
* sm/certreqgen.c
** Improve error reporting
** Do some basic checks on the supplied DNs
* sm/certchain.c
** When a certificate chain was sucessfully verified, make ephemeral certs used in this chain permanent.
** figure out how to auto retrieve a key by serialno+issuer.
Dirmngr is currently not able to parse more than the CN.
* sm/decrypt.c
** replace leading zero in integer hack by a cleaner solution
* sm/gpgsm.c
** Support --output for all commands
** mark all unimplemented commands and options.
** Print a hint when MD2 is the cause for a problem.
** Implement --default-key
** Using --export-secret-key-p12 with a non-pth agent
This leads to a lockup because gpgsm is still accessing the agent
while gpg-protect-tool wants to pop up the pinentry. Solution is
to release the connection. This is not trivial, thus we are going
to do that while changing gpgsm to allow concurrent operations.
+** support the anyPolicy semantic
+** Check that we are really following the verification procedures in rfc3280.
* 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
* agent/gpg-agent.c
** A SIGHUP should also restart the scdaemon
- But do this only after all connections terminated.
- As of now we only send a RESET.
+ But do this only after all connections terminated. As of now we
+ only send a RESET.
* agent/command.c
** Make sure that secure memory is used where appropriate
* agent/pkdecrypt.c, agent/pksign.c
** Don't use stdio to return results.
+** Support DSA
* agent/divert-scd.c
Remove the agent_reset_scd kludge.
* Move pkcs-1 encoding into libgcrypt.
* Use a MAC to protect some files.
* sm/export.c
** Return an error code or a status info per user ID.
* Where is http.c, regcomp.c, srv.c, w32reg.c ?
* scd/sc-investigate
** Enhance with card compatibility check
* 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.
** Add a test to check the extkeyusage.
* doc/
** Explain how to setup a root CA key as trusted
** Explain how trustlist.txt might be managed.
* Requirements by the BSI
** Support authorityKeyIdentifier.keyIdentifier
This needs support in libksba/src/cert.c as well as in sm/*.c.
Need test certs as well. Same goes for CRL authorityKeyIdentifier.
** For pkcs#10 request header.
We use "NEW CERTIFICATE REQUEST" the specs say "CERTIFICATE
REQUEST" should be used. However it seems that their CA software
is also able to use our header. Binary pkcs#10 request are not
allowed.
** Dirmngr: name subordination (nameRelativeToCRLIssuer)
is not yet supported by Dirmngr.
** Dirmngr: CRL DP URI
The CRL DP shall use an URI for LDAP without a host name. The host
name shall be looked by using the DN in the URI. We don't implement
this yet. Solution is to have a mapping DN->host in our ldapservers
configuration file.
diff --git a/configure.ac b/configure.ac
index f34faf469..d04475f6b 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1,1146 +1,1157 @@
# configure.ac - for GnuPG 1.9
# Copyright (C) 1998, 1999, 2000, 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
# Process this file with autoconf to produce a configure script.
AC_PREREQ(2.52)
min_automake_version="1.7.6"
# Version number: Remember to change it immediately *after* a release.
# Add a "-cvs" prefix for non-released code.
AC_INIT(gnupg, 1.9.11-cvs, gnupg-devel@gnupg.org)
# Set development_version to yes if the minor number is odd or you
# feel that the default check for a development version is not
# sufficient.
development_version=yes
NEED_GPG_ERROR_VERSION=0.7
NEED_LIBGCRYPT_API=1
NEED_LIBGCRYPT_VERSION=1.1.94
NEED_LIBASSUAN_VERSION=0.6.6
NEED_KSBA_VERSION=0.9.7
NEED_OPENSC_VERSION=0.8.0
PACKAGE=$PACKAGE_NAME
PACKAGE_GT=${PACKAGE_NAME}2
VERSION=$PACKAGE_VERSION
AC_CONFIG_AUX_DIR(scripts)
AC_CONFIG_SRCDIR(sm/gpgsm.c)
AM_CONFIG_HEADER(config.h)
AC_CANONICAL_TARGET()
AM_INIT_AUTOMAKE($PACKAGE, $VERSION)
AC_GNU_SOURCE
# Some status variables to give feedback at the end of a configure run
have_gpg_error=no
have_libgcrypt=no
have_libassuan=no
have_ksba=no
have_opensc=no
have_pth=no
GNUPG_BUILD_PROGRAM(gpg, yes)
GNUPG_BUILD_PROGRAM(gpgsm, yes)
GNUPG_BUILD_PROGRAM(agent, yes)
GNUPG_BUILD_PROGRAM(scdaemon, yes)
AC_SUBST(PACKAGE)
AC_SUBST(PACKAGE_GT)
AC_SUBST(VERSION)
AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of this package])
AC_DEFINE_UNQUOTED(PACKAGE_GT, "$PACKAGE_GT",
[Name of this package for gettext])
AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version of this package])
AC_DEFINE_UNQUOTED(PACKAGE_BUGREPORT, "$PACKAGE_BUGREPORT",
[Bug report address])
AC_DEFINE_UNQUOTED(NEED_LIBGCRYPT_VERSION, "$NEED_LIBGCRYPT_VERSION",
[Required version of Libgcrypt])
AC_DEFINE_UNQUOTED(NEED_KSBA_VERSION, "$NEED_KSBA_VERSION",
[Required version of Libksba])
# The default is to use the modules from this package and the few
# other packages in a standard place; i.e where this package gets
# installed. With these options it is possible to override these
# ${prefix} depended values with fixed paths, which can't be replaced
# at make time. See also am/cmacros.am and the defaults in AH_BOTTOM.
AC_ARG_WITH(agent-pgm,
[ --with-agent-pgm=PATH Use PATH as the default for the agent)],
GNUPG_AGENT_PGM="$withval", GNUPG_AGENT_PGM="" )
AC_SUBST(GNUPG_AGENT_PGM)
AM_CONDITIONAL(GNUPG_AGENT_PGM, test -n "$GNUPG_AGENT_PGM")
show_gnupg_agent_pgm="(default)"
test -n "$GNUPG_AGENT_PGM" && show_gnupg_agent_pgm="$GNUPG_AGENT_PGM"
AC_ARG_WITH(pinentry-pgm,
[ --with-pinentry-pgm=PATH Use PATH as the default for the pinentry)],
GNUPG_PINENTRY_PGM="$withval", GNUPG_PINENTRY_PGM="" )
AC_SUBST(GNUPG_PINENTRY_PGM)
AM_CONDITIONAL(GNUPG_PINENTRY_PGM, test -n "$GNUPG_PINENTRY_PGM")
show_gnupg_pinentry_pgm="(default)"
test -n "$GNUPG_PINENTRY_PGM" && show_gnupg_pinentry_pgm="$GNUPG_PINENTRY_PGM"
AC_ARG_WITH(scdaemon-pgm,
[ --with-scdaemon-pgm=PATH Use PATH as the default for the scdaemon)],
GNUPG_SCDAEMON_PGM="$withval", GNUPG_SCDAEMON_PGM="" )
AC_SUBST(GNUPG_SCDAEMON_PGM)
AM_CONDITIONAL(GNUPG_SCDAEMON_PGM, test -n "$GNUPG_SCDAEMON_PGM")
show_gnupg_scdaemon_pgm="(default)"
test -n "$GNUPG_SCDAEMON_PGM" && show_gnupg_scdaemon_pgm="$GNUPG_SCDAEMON_PGM"
AC_ARG_WITH(dirmngr-pgm,
[ --with-dirmngr-pgm=PATH Use PATH as the default for the dirmngr)],
GNUPG_DIRMNGR_PGM="$withval", GNUPG_DIRMNGR_PGM="" )
AC_SUBST(GNUPG_DIRMNGR_PGM)
AM_CONDITIONAL(GNUPG_DIRMNGR_PGM, test -n "$GNUPG_DIRMNGR_PGM")
show_gnupg_dirmngr_pgm="(default)"
test -n "$GNUPG_DIRMNGR_PGM" && show_gnupg_dirmngr_pgm="$GNUPG_DIRMNGR_PGM"
AC_ARG_WITH(protect-tool-pgm,
[ --with-protect-tool-pgm=PATH Use PATH as the default for the protect-tool)],
GNUPG_PROTECT_TOOL_PGM="$withval", GNUPG_PROTECT_TOOL_PGM="" )
AC_SUBST(GNUPG_PROTECT_TOOL_PGM)
AM_CONDITIONAL(GNUPG_PROTECT_TOOL_PGM, test -n "$GNUPG_PROTECT_TOOL_PGM")
show_gnupg_protect_tool_pgm="(default)"
test -n "$GNUPG_PROTECT_TOOL_PGM" \
&& show_gnupg_protect_tool_pgm="$GNUPG_PROTECT_TOOL_PGM"
# Some folks want to use only the agent form this packet. Make it
# easier for them by providing the configure option
# --enable-only-agent.
AC_ARG_ENABLE(agent-only,
AC_HELP_STRING([--enable-agent-only],[build only the gpg-agent]),
build_agent_only=$enableval)
# Configure option to allow ot disallow execution of external
# programs, like a photo viewer.
AC_MSG_CHECKING([whether to enable external program execution])
AC_ARG_ENABLE(exec,
AC_HELP_STRING([--disable-exec],[disable all external program execution]),
use_exec=$enableval)
AC_MSG_RESULT($use_exec)
if test "$use_exec" = no ; then
AC_DEFINE(NO_EXEC,1,[Define to disable all external program execution])
fi
if test "$use_exec" = yes ; then
AC_MSG_CHECKING([whether to enable photo ID viewing])
AC_ARG_ENABLE(photo-viewers,
[ --disable-photo-viewers disable photo ID viewers],
[if test "$enableval" = no ; then
AC_DEFINE(DISABLE_PHOTO_VIEWER,1,[define to disable photo viewing])
fi],enableval=yes)
gnupg_cv_enable_photo_viewers=$enableval
AC_MSG_RESULT($enableval)
if test "$gnupg_cv_enable_photo_viewers" = yes ; then
AC_MSG_CHECKING([whether to use a fixed photo ID viewer])
AC_ARG_WITH(photo-viewer,
[ --with-photo-viewer=FIXED_VIEWER set a fixed photo ID viewer],
[if test "$withval" = yes ; then
withval=no
elif test "$withval" != no ; then
AC_DEFINE_UNQUOTED(FIXED_PHOTO_VIEWER,"$withval",
[if set, restrict photo-viewer to this])
fi],withval=no)
AC_MSG_RESULT($withval)
fi
AC_MSG_CHECKING([whether to enable external keyserver helpers])
AC_ARG_ENABLE(keyserver-helpers,
[ --disable-keyserver-helpers disable all external keyserver support],
[if test "$enableval" = no ; then
AC_DEFINE(DISABLE_KEYSERVER_HELPERS,1,
[define to disable keyserver helpers])
fi],enableval=yes)
gnupg_cv_enable_keyserver_helpers=$enableval
AC_MSG_RESULT($enableval)
if test "$gnupg_cv_enable_keyserver_helpers" = yes ; then
AC_MSG_CHECKING([whether LDAP keyserver support is requested])
AC_ARG_ENABLE(ldap,
[ --disable-ldap disable LDAP keyserver interface],
try_ldap=$enableval, try_ldap=yes)
AC_MSG_RESULT($try_ldap)
AC_MSG_CHECKING([whether HKP keyserver support is requested])
AC_ARG_ENABLE(hkp,
[ --disable-hkp disable HKP keyserver interface],
try_hkp=$enableval, try_hkp=yes)
AC_MSG_RESULT($try_hkp)
if test "$try_hkp" = yes ; then
AC_SUBST(GPGKEYS_HKP,"gpgkeys_hkp$EXEEXT")
fi
AC_MSG_CHECKING([whether email keyserver support is requested])
AC_ARG_ENABLE(mailto,
[ --disable-mailto disable email keyserver interface],
try_mailto=$enableval, try_mailto=yes)
AC_MSG_RESULT($try_mailto)
fi
AC_MSG_CHECKING([whether keyserver exec-path is enabled])
AC_ARG_ENABLE(keyserver-path,
[ --disable-keyserver-path disable the exec-path option for keyserver helpers],
[if test "$enableval" = no ; then
AC_DEFINE(DISABLE_KEYSERVER_PATH,1,[define to disable exec-path for keyserver helpers])
fi],enableval=yes)
AC_MSG_RESULT($enableval)
fi
AC_MSG_CHECKING([whether the included zlib is requested])
AC_ARG_WITH(included-zlib,
[ --with-included-zlib use the zlib code included here],
[g10_force_zlib=yes], [g10_force_zlib=no] )
AC_MSG_RESULT($g10_force_zlib)
dnl
dnl Check whether we want to use Linux capabilities
dnl
AC_MSG_CHECKING([whether use of capabilities is requested])
AC_ARG_WITH(capabilities,
[ --with-capabilities use linux capabilities [default=no]],
[use_capabilities="$withval"],[use_capabilities=no])
AC_MSG_RESULT($use_capabilities)
AH_BOTTOM([
/* Some global constants. */
#ifdef HAVE_DRIVE_LETTERS
#define GNUPG_DEFAULT_HOMEDIR "c:/gnupg"
#elif defined(__VMS)
#define GNUPG_DEFAULT_HOMEDIR "/SYS\$LOGIN/gnupg"
#else
#define GNUPG_DEFAULT_HOMEDIR "~/.gnupg"
#endif
#define GNUPG_PRIVATE_KEYS_DIR "private-keys-v1.d"
/* Tell libgcrypt not to use its own libgpg-error implementation. */
#define USE_LIBGPG_ERROR 1
/* This is the major version number of GnuPG so that
source included files can test for this. Note, that\
we use 2 here even for GnuPG 1.9.x. */
#define GNUPG_MAJOR_VERSION 2
/* Now to separate file name parts.
Please note that the string version must not contain more
than one character because the code assumes strlen()==1 */
#ifdef HAVE_DOSISH_SYSTEM
#define DIRSEP_C '\\'
#define EXTSEP_C '.'
#define DIRSEP_S "\\"
#define EXTSEP_S "."
#else
#define DIRSEP_C '/'
#define EXTSEP_C '.'
#define DIRSEP_S "/"
#define EXTSEP_S "."
#endif
/* This is the same as VERSION, but should be overridden if the
platform cannot handle things like dots '.' in filenames. Set
SAFE_VERSION_DOT and SAFE_VERSION_DASH to whatever SAFE_VERSION
uses for dots and dashes. */
#define SAFE_VERSION VERSION
#define SAFE_VERSION_DOT '.'
#define SAFE_VERSION_DASH '-'
/* For some systems (DOS currently), we hardcode the path here. For
POSIX systems the values are constructed by the Makefiles, so that
the values may be overridden by the make invocations; this is to
comply with the GNU coding standards. */
#ifdef HAVE_DRIVE_LETTERS
#define GNUPG_BINDIR "c:\\gnupg"
#define GNUPG_LIBEXECDIR "c:\\lib\\gnupg"
#define GNUPG_LIBDIR "c:\\lib\\gnupg"
#define GNUPG_DATADIR "c:\\lib\\gnupg"
#endif
/* Setup the hardwired names of modules. */
#ifndef GNUPG_DEFAULT_AGENT
#define GNUPG_DEFAULT_AGENT ( GNUPG_BINDIR DIRSEP_S "gpg-agent" )
#endif
#ifndef GNUPG_DEFAULT_PINENTRY
#define GNUPG_DEFAULT_PINENTRY ( GNUPG_BINDIR DIRSEP_S "pinentry" )
#endif
#ifndef GNUPG_DEFAULT_SCDAEMON
#define GNUPG_DEFAULT_SCDAEMON ( GNUPG_BINDIR DIRSEP_S "scdaemon" )
#endif
#ifndef GNUPG_DEFAULT_DIRMNGR
#define GNUPG_DEFAULT_DIRMNGR ( GNUPG_BINDIR DIRSEP_S "dirmngr" )
#endif
#ifndef GNUPG_DEFAULT_PROTECT_TOOL
#define GNUPG_DEFAULT_PROTECT_TOOL \
( GNUPG_LIBEXECDIR DIRSEP_S "gpg-protect-tool" )
#endif
/* Derive some other constants. */
#if !(defined(HAVE_FORK) && defined(HAVE_PIPE) && defined(HAVE_WAITPID))
#define EXEC_TEMPFILE_ONLY
#endif
])
AM_MAINTAINER_MODE
# Checks for programs.
AC_PROG_MAKE_SET
AM_SANITY_CHECK
missing_dir=`cd $ac_aux_dir && pwd`
AM_MISSING_PROG(ACLOCAL, aclocal, $missing_dir)
AM_MISSING_PROG(AUTOCONF, autoconf, $missing_dir)
AM_MISSING_PROG(AUTOMAKE, automake, $missing_dir)
AM_MISSING_PROG(AUTOHEADER, autoheader, $missing_dir)
AM_MISSING_PROG(MAKEINFO, makeinfo, $missing_dir)
AC_PROG_AWK
AC_PROG_CC
AC_PROG_CPP
AC_PROG_INSTALL
AC_PROG_LN_S
AC_PROG_MAKE_SET
AC_PROG_RANLIB
AC_CHECK_TOOL(AR, ar, :)
AC_PATH_PROG(PERL,"perl")
AC_ISC_POSIX
AC_SYS_LARGEFILE
AC_CHECK_PROG(DOCBOOK_TO_MAN, docbook-to-man, yes, no)
AM_CONDITIONAL(HAVE_DOCBOOK_TO_MAN, test "$ac_cv_prog_DOCBOOK_TO_MAN" = yes)
GNUPG_CHECK_FAQPROG
GNUPG_CHECK_DOCBOOK_TO_TEXI
try_gettext=yes
have_dosish_system=no
case "${target}" in
*-*-mingw32*)
# special stuff for Windoze NT
ac_cv_have_dev_random=no
AC_DEFINE(USE_ONLY_8DOT3,1,
[set this to limit filenames to the 8.3 format])
AC_DEFINE(HAVE_DRIVE_LETTERS,1,
[defined if we must run on a stupid file system])
AC_DEFINE(USE_SIMPLE_GETTEXT,1,
[because the Unix gettext has too much overhead on
MingW32 systems and these systems lack Posix functions,
we use a simplified version of gettext])
have_dosish_system=yes
try_gettext="no"
;;
i?86-emx-os2 | i?86-*-os2*emx )
# OS/2 with the EMX environment
ac_cv_have_dev_random=no
AC_DEFINE(HAVE_DRIVE_LETTERS)
have_dosish_system=yes
try_gettext="no"
;;
i?86-*-msdosdjgpp*)
# DOS with the DJGPP environment
ac_cv_have_dev_random=no
AC_DEFINE(HAVE_DRIVE_LETTERS)
have_dosish_system=yes
try_gettext="no"
;;
*-*-freebsd*)
# FreeBSD
CPPFLAGS="$CPPFLAGS -I/usr/local/include"
LDFLAGS="$LDFLAGS -L/usr/local/lib"
;;
*-*-hpux*)
if test -z "$GCC" ; then
CFLAGS="$CFLAGS -Ae -D_HPUX_SOURCE"
fi
;;
*-dec-osf4*)
if test -z "$GCC" ; then
# Suppress all warnings
# to get rid of the unsigned/signed char mismatch warnings.
CFLAGS="$CFLAGS -w"
fi
;;
*-dec-osf5*)
if test -z "$GCC" ; then
# Use the newer compiler `-msg_disable ptrmismatch' to
# get rid of the unsigned/signed char mismatch warnings.
# Using this may hide other pointer mismatch warnings, but
# it at least lets other warning classes through
CFLAGS="$CFLAGS -msg_disable ptrmismatch"
fi
;;
m68k-atari-mint)
;;
*)
;;
esac
if test "$have_dosish_system" = yes; then
AC_DEFINE(HAVE_DOSISH_SYSTEM,1,
[defined if we run on some of the PCDOS like systems
(DOS, Windoze. OS/2) with special properties like
no file modes])
fi
AM_CONDITIONAL(HAVE_DOSISH_SYSTEM, test "$have_dosish_system" = yes)
#
# Checks for libraries.
#
#
# libgpg-error is a library with error codes shared between GnuPG
# related projects.
#
AM_PATH_GPG_ERROR("$NEED_GPG_ERROR_VERSION",
have_gpg_error=yes,have_gpg_error=no)
#
# Libgcrypt is our generic crypto library
#
AM_PATH_LIBGCRYPT("$NEED_LIBGCRYPT_API:$NEED_LIBGCRYPT_VERSION",
have_libgcrypt=yes,have_libgcrypt=no)
#
# libassuan is used for IPC
#
AM_PATH_LIBASSUAN("$NEED_LIBASSUAN_VERSION",
have_libassuan=yes,have_libassuan=no)
#
# libksba is our X.509 support library
#
AM_PATH_KSBA("$NEED_KSBA_VERSION",have_ksba=yes,have_ksba=no)
#
# libusb allows us to use the integrated CCID smartcard reader driver.
#
AC_CHECK_LIB(usb, usb_bulk_write,
[ LIBUSB_LIBS="$LIBUSB_LIBS -lusb"
AC_DEFINE(HAVE_LIBUSB,1,
[defined if libusb is available])
])
AC_SUBST(LIBUSB_LIBS)
AC_CHECK_FUNCS(usb_create_match)
#
# Check wether it is necessary to link against libdl.
#
LIBS=""
AC_SEARCH_LIBS(dlopen, c dl,,,)
DL_LIBS=$LIBS
AC_SUBST(DL_LIBS)
#
# OpenSC is needed by the SCdaemon - if it is not availbale we can only
# build a limited SCdaemon
#
AM_PATH_OPENSC("$NEED_OPENSC_VERSION",have_opensc=yes,have_opensc=no)
if test $have_opensc = yes; then
AC_DEFINE(HAVE_OPENSC,1,
[defined if the OpenSC library is available])
fi
AM_CONDITIONAL(HAVE_OPENSC, test "$have_opensc" = "yes")
#
# Check whether the (highly desirable) GNU Pth library is available
#
AC_ARG_WITH(pth-prefix,
AC_HELP_STRING([--with-pth-prefix=PFX],
[prefix where GNU Pth is installed (optional)]),
pth_config_prefix="$withval", pth_config_prefix="")
if test x$pth_config_prefix != x ; then
PTH_CONFIG="$pth_config_prefix/bin/pth-config"
fi
AC_PATH_PROG(PTH_CONFIG, pth-config, no)
if test "$PTH_CONFIG" = "no"; then
AC_MSG_WARN([[
***
*** To support concurrent access to the gpg-agent and the SCdaemon
*** we need the support of the GNU Portable Threads Library.
*** Download it from ftp://ftp.gnu.org/gnu/pth/
*** On a Debian GNU/Linux system you might want to try
*** apt-get install libpth-dev
***]])
else
GNUPG_PTH_VERSION_CHECK(1.3.7)
if test $have_pth = yes; then
PTH_CFLAGS=`$PTH_CONFIG --cflags`
PTH_LIBS=`$PTH_CONFIG --ldflags`
PTH_LIBS="$PTH_LIBS `$PTH_CONFIG --libs`"
AC_DEFINE(USE_GNU_PTH, 1,
[Defined if the GNU Portable Thread Library should be used])
fi
fi
AC_SUBST(PTH_CFLAGS)
AC_SUBST(PTH_LIBS)
AC_ARG_ENABLE(threads,
AC_HELP_STRING([--disable-threads],[allow building without Pth support]);
)
dnl Must check for network library requirements before doing link tests
dnl for ldap, for example. If ldap libs are static (or dynamic and without
dnl ELF runtime link paths), then link will fail and LDAP support won't
dnl be detected.
AC_CHECK_FUNC(gethostbyname, , AC_CHECK_LIB(nsl, gethostbyname,
[NETLIBS="-lnsl $NETLIBS"]))
AC_CHECK_FUNC(setsockopt, , AC_CHECK_LIB(socket, setsockopt,
[NETLIBS="-lsocket $NETLIBS"]))
dnl Now try for the resolver functions so we can use DNS SRV
AC_ARG_ENABLE(dns-srv,
AC_HELP_STRING([--disable-dns-srv],[disable the use of DNS SRV in HKP]),
use_dns_srv=$enableval,use_dns_srv=yes)
if test x"$try_hkp" = xyes && test x"$use_dns_srv" = xyes ; then
_srv_save_libs=$LIBS
LIBS=""
# the double underscore thing is a glibc-ism?
AC_SEARCH_LIBS(res_query,resolv bind,,
AC_SEARCH_LIBS(__res_query,resolv bind,,use_dns_srv=no))
AC_SEARCH_LIBS(dn_expand,resolv bind,,
AC_SEARCH_LIBS(__dn_expand,resolv bind,,use_dns_srv=no))
AC_SEARCH_LIBS(dn_skipname,resolv bind,,
AC_SEARCH_LIBS(__dn_skipname,resolv bind,,use_dns_srv=no))
if test x"$use_dns_srv" = xyes ; then
AC_DEFINE(USE_DNS_SRV,1,[define to use DNS SRV])
SRVLIBS=$LIBS
else
AC_MSG_WARN([Resolver functions not found. Disabling DNS SRV.])
fi
LIBS=$_srv_save_libs
fi
AC_SUBST(SRVLIBS)
# Try and link a LDAP test program to weed out unusable LDAP
# libraries. -lldap [-llber [-lresolv]] is for OpenLDAP. OpenLDAP in
# general is terrible with creating weird dependencies. If all else
# fails, the user can play guess-the-dependency by using something
# like ./configure LDAPLIBS="-Lfoo -lbar"
if test "$try_ldap" = yes ; then
for MY_LDAPLIBS in ${LDAPLIBS+"$LDAPLIBS"} "-lldap" "-lldap -llber" "-lldap -llber -lresolv"; do
_ldap_save_libs=$LIBS
LIBS="$MY_LDAPLIBS $NETLIBS $LIBS"
AC_MSG_CHECKING([whether LDAP via \"$MY_LDAPLIBS\" is present and sane])
AC_TRY_LINK([#include <ldap.h>],[ldap_open("foobar",1234);],
[gnupg_cv_func_ldap_init=yes],[gnupg_cv_func_ldap_init=no])
AC_MSG_RESULT([$gnupg_cv_func_ldap_init])
if test $gnupg_cv_func_ldap_init = no; then
AC_MSG_CHECKING([whether I can make LDAP be sane with lber.h])
AC_TRY_LINK([#include <lber.h>
#include <ldap.h>],[ldap_open("foobar",1234);],
[gnupg_cv_func_ldaplber_init=yes],[gnupg_cv_func_ldaplber_init=no])
AC_MSG_RESULT([$gnupg_cv_func_ldaplber_init])
fi
if test "$gnupg_cv_func_ldaplber_init" = yes ; then
AC_DEFINE(NEED_LBER_H,1,[Define if the LDAP library requires including lber.h before ldap.h])
fi
if test "$gnupg_cv_func_ldap_init" = yes || \
test "$gnupg_cv_func_ldaplber_init" = yes ; then
LDAPLIBS=$MY_LDAPLIBS
GPGKEYS_LDAP="gpgkeys_ldap$EXEEXT"
AC_MSG_CHECKING([whether LDAP supports ldap_get_option])
if test "$gnupg_cv_func_ldap_init" = yes ; then
AC_TRY_LINK([#include <ldap.h>],
[ldap_get_option((void *)0,0,(void *)0);],
[gnupg_cv_func_ldap_get_option=yes],
[gnupg_cv_func_ldap_get_option=no])
else
AC_TRY_LINK([#include <lber.h>
#include <ldap.h>],[ldap_get_option((void *)0,0,(void *)0);],
[gnupg_cv_func_ldap_get_option=yes],
[gnupg_cv_func_ldap_get_option=no])
fi
AC_MSG_RESULT([$gnupg_cv_func_ldap_get_option])
if test "$gnupg_cv_func_ldap_get_option" = yes ; then
AC_DEFINE(HAVE_LDAP_GET_OPTION,1,[Define if the LDAP library has ldap_get_option])
else
AC_MSG_CHECKING([whether LDAP supports ld_errno])
if test "$gnupg_cv_func_ldap_init" = yes ; then
AC_TRY_COMPILE([#include <ldap.h>],
[LDAP *ldap; ldap->ld_errno;],
[gnupg_cv_func_ldap_ld_errno=yes],
[gnupg_cv_func_ldap_ld_errno=no])
else
AC_TRY_LINK([#include <lber.h>
#include <ldap.h>],[LDAP *ldap; ldap->ld_errno;],
[gnupg_cv_func_ldap_ld_errno=yes],
[gnupg_cv_func_ldap_ld_errno=no])
fi
AC_MSG_RESULT([$gnupg_cv_func_ldap_ld_errno])
if test "$gnupg_cv_func_ldap_ld_errno" = yes ; then
AC_DEFINE(HAVE_LDAP_LD_ERRNO,1,[Define if the LDAP library supports ld_errno])
fi
fi
fi
LIBS=$_ldap_save_libs
if test "$GPGKEYS_LDAP" != "" ; then break; fi
done
fi
AC_SUBST(GPGKEYS_LDAP)
AC_SUBST(LDAPLIBS)
dnl This isn't necessarily sendmail itself, but anything that gives a
dnl sendmail-ish interface to the outside world. That includes qmail,
dnl postfix, etc. Basically, anything that can handle "sendmail -t".
if test "$try_mailto" = yes ; then
AC_ARG_WITH(mailprog,[ --with-mailprog=NAME use "NAME -t" for mail transport],,with_mailprog=yes)
if test "$with_mailprog" = yes ; then
AC_PATH_PROG(SENDMAIL,sendmail,,$PATH:/usr/sbin:/usr/libexec:/usr/lib)
if test "$ac_cv_path_SENDMAIL" ; then
GPGKEYS_MAILTO="gpgkeys_mailto"
fi
elif test "$with_mailprog" != no ; then
AC_MSG_CHECKING([for a mail transport program])
AC_SUBST(SENDMAIL,$with_mailprog)
AC_MSG_RESULT($with_mailprog)
GPGKEYS_MAILTO="gpgkeys_mailto"
fi
fi
AC_SUBST(GPGKEYS_MAILTO)
case "${target}" in
*-*-mingw32*)
PRINTABLE_OS_NAME="MingW32"
;;
*-*-cygwin*)
PRINTABLE_OS_NAME="Cygwin"
;;
i?86-emx-os2 | i?86-*-os2*emx )
PRINTABLE_OS_NAME="OS/2"
;;
i?86-*-msdosdjgpp*)
PRINTABLE_OS_NAME="MSDOS/DJGPP"
try_dynload=no
;;
*-linux*)
PRINTABLE_OS_NAME="GNU/Linux"
;;
*)
PRINTABLE_OS_NAME=`uname -s || echo "Unknown"`
;;
esac
AC_DEFINE_UNQUOTED(PRINTABLE_OS_NAME, "$PRINTABLE_OS_NAME",
[A human readable text with the name of the OS])
AM_GNU_GETTEXT_VERSION(0.12.1)
if test "$try_gettext" = yes; then
AM_GNU_GETTEXT(,[need-ngettext])
# gettext requires some extra checks. These really should be part of
# the basic AM_GNU_GETTEXT macro. TODO: move other gettext-specific
# function checks to here.
AC_CHECK_FUNCS(strchr)
else
USE_NLS=no
USE_INCLUDED_LIBINTL=no
BUILD_INCLUDED_LIBINTL=no
AC_SUBST(USE_NLS)
AC_SUBST(USE_INCLUDED_LIBINTL)
AC_SUBST(BUILD_INCLUDED_LIBINTL)
fi
# Checks for header files.
AC_HEADER_STDC
AC_CHECK_HEADERS(string.h unistd.h langinfo.h termio.h locale.h)
# Checks for typedefs, structures, and compiler characteristics.
AC_C_CONST
AC_C_INLINE
AC_TYPE_SIZE_T
AC_TYPE_SIGNAL
AC_DECL_SYS_SIGLIST
GNUPG_CHECK_ENDIAN
GNUPG_CHECK_TYPEDEF(byte, HAVE_BYTE_TYPEDEF)
GNUPG_CHECK_TYPEDEF(ushort, HAVE_USHORT_TYPEDEF)
GNUPG_CHECK_TYPEDEF(ulong, HAVE_ULONG_TYPEDEF)
GNUPG_CHECK_TYPEDEF(u16, HAVE_U16_TYPEDEF)
GNUPG_CHECK_TYPEDEF(u32, HAVE_U32_TYPEDEF)
AC_CHECK_SIZEOF(unsigned short)
AC_CHECK_SIZEOF(unsigned int)
AC_CHECK_SIZEOF(unsigned long)
AC_CHECK_SIZEOF(unsigned long long)
# Ensure that we have UINT64_C before we bother to check for uint64_t
# fixme: really needed in gnupg? I think it is only useful in libcgrypt.
AC_CACHE_CHECK([for UINT64_C],[gnupg_cv_uint64_c_works],
AC_COMPILE_IFELSE(AC_LANG_PROGRAM([#include <inttypes.h>
uint64_t foo=UINT64_C(42);]),gnupg_cv_uint64_c_works=yes,gnupg_cv_uint64_c_works=no))
if test "$gnupg_cv_uint64_c_works" = "yes" ; then
AC_CHECK_SIZEOF(uint64_t)
fi
if test "$ac_cv_sizeof_unsigned_short" = "0" \
|| test "$ac_cv_sizeof_unsigned_int" = "0" \
|| test "$ac_cv_sizeof_unsigned_long" = "0"; then
AC_MSG_WARN([Hmmm, something is wrong with the sizes - using defaults]);
fi
dnl Do we have any 64-bit data types?
if test "$ac_cv_sizeof_unsigned_int" != "8" \
&& test "$ac_cv_sizeof_unsigned_long" != "8" \
&& test "$ac_cv_sizeof_unsigned_long_long" != "8" \
&& test "$ac_cv_sizeof_uint64_t" != "8"; then
AC_MSG_WARN([No 64-bit types. Disabling SHA-384, and SHA-512])
else
if test x"$use_sha512" = xyes ; then
AC_SUBST(SHA512_O,sha512.o)
AC_DEFINE(USE_SHA512,1,[Define to include the SHA-384 and SHA-512 digests])
fi
fi
# fixme: do we really need this - it should be encapsulated in libassuan
GNUPG_SYS_SO_PEERCRED
# Checks for library functions.
AC_FUNC_FSEEKO
AC_FUNC_VPRINTF
AC_FUNC_FORK
AC_CHECK_FUNCS(strerror stpcpy strsep strlwr tcgetattr strtoul mmap)
AC_CHECK_FUNCS(strcasecmp strncasecmp ctermid times gmtime_r)
AC_CHECK_FUNCS(memmove gettimeofday getrusage setrlimit clock_gettime)
AC_CHECK_FUNCS(atexit raise getpagesize strftime nl_langinfo setlocale)
AC_CHECK_FUNCS(waitpid wait4 sigaction sigprocmask rand pipe stat getaddrinfo)
AC_CHECK_TYPES([struct sigaction, sigset_t],,,[#include <signal.h>])
# These are needed by libjnlib - fixme: we should have macros for them
AC_CHECK_FUNCS(memicmp stpcpy strlwr strtoul memmove stricmp strtol)
AC_CHECK_FUNCS(getrusage setrlimit stat setlocale)
AC_CHECK_FUNCS(flockfile funlockfile fopencookie funopen)
AC_REPLACE_FUNCS(vasprintf)
AC_REPLACE_FUNCS(mkdtemp)
AC_REPLACE_FUNCS(fseeko ftello)
AC_REPLACE_FUNCS(isascii)
AC_REPLACE_FUNCS(putc_unlocked)
#
# check for gethrtime and run a testprogram to see whether
# it is broken. It has been reported that some Solaris and HP UX systems
# raise an SIGILL
#
# fixme: Do we need this - iirc, this is only used by libgcrypt.
#
AC_CACHE_CHECK([for gethrtime],
[gnupg_cv_func_gethrtime],
[AC_TRY_LINK([#include <sys/times.h>],[
hrtime_t tv;
tv = gethrtime();
],
[gnupg_cv_func_gethrtime=yes],
[gnupg_cv_func_gethrtime=no])
])
if test $gnupg_cv_func_gethrtime = yes; then
AC_DEFINE([HAVE_GETHRTIME], 1,
[Define if you have the `gethrtime(2)' function.])
AC_CACHE_CHECK([whether gethrtime is broken],
[gnupg_cv_func_broken_gethrtime],
[AC_TRY_RUN([
#include <sys/times.h>
int main () {
hrtime_t tv;
tv = gethrtime();
}
],
[gnupg_cv_func_broken_gethrtime=no],
[gnupg_cv_func_broken_gethrtime=yes],
[gnupg_cv_func_broken_gethrtime=assume-no])
])
if test $gnupg_cv_func_broken_gethrtime = yes; then
AC_DEFINE([HAVE_BROKEN_GETHRTIME], 1,
[Define if `gethrtime(2)' does not work correctly i.e. issues a SIGILL.])
fi
fi
GNUPG_CHECK_MLOCK
GNUPG_FUNC_MKDIR_TAKES_ONE_ARG
dnl
dnl Check whether we can use Linux capabilities as requested
dnl
# fixme: Still required?
#
if test "$use_capabilities" = "yes" ; then
use_capabilities=no
AC_CHECK_HEADERS(sys/capability.h)
if test "$ac_cv_header_sys_capability_h" = "yes" ; then
AC_CHECK_LIB(cap, cap_init, ac_need_libcap=1)
if test "$ac_cv_lib_cap_cap_init" = "yes"; then
AC_DEFINE(USE_CAPABILITIES,1,
[define if capabilities should be used])
AC_SUBST(CAPLIBS,"-lcap")
use_capabilities=yes
fi
fi
if test "$use_capabilities" = "no" ; then
AC_MSG_WARN([[
***
*** The use of capabilities on this system is not possible.
*** You need a recent Linux kernel and some patches:
*** fcaps-2.2.9-990610.patch (kernel patch for 2.2.9)
*** fcap-module-990613.tar.gz (kernel module)
*** libcap-1.92.tar.gz (user mode library and utilities)
*** And you have to configure the kernel with CONFIG_VFS_CAP_PLUGIN
*** set (filesystems menu). Be warned: This code is *really* ALPHA.
***]])
fi
fi
# Sanity check regex. Tests adapted from mutt.
AC_MSG_CHECKING([whether regular expression support is requested])
AC_ARG_ENABLE(regex,
[ --disable-regex do not handle regular expressions in trust sigs],
use_regex=$enableval, use_regex=yes)
AC_MSG_RESULT($use_regex)
if test "$use_regex" = yes ; then
AC_MSG_CHECKING([whether the included regex lib is requested])
AC_ARG_WITH(included-regex,
[ --with-included-regex use the included GNU regex library],
[gnupg_cv_included_regex=yes],[gnupg_cv_included_regex=no])
AC_MSG_RESULT($gnupg_cv_included_regex)
if test $gnupg_cv_included_regex = no ; then
# Does the system have regex functions at all?
AC_CHECK_FUNC(regcomp,gnupg_cv_included_regex=no,
gnupg_cv_included_regex=yes)
fi
if test $gnupg_cv_included_regex = no ; then
AC_CACHE_CHECK([whether your system's regexp library is broken],
[gnupg_cv_regex_broken],
AC_TRY_RUN([
#include <unistd.h>
#include <regex.h>
main() { regex_t blah ; regmatch_t p; p.rm_eo = p.rm_eo; return regcomp(&blah, "foo.*bar", REG_NOSUB) || regexec (&blah, "foobar", 0, NULL, 0); }],
gnupg_cv_regex_broken=no, gnupg_cv_regex_broken=yes, gnupg_cv_regex_broken=yes))
if test $gnupg_cv_regex_broken = yes ; then
AC_MSG_WARN(your regex is broken - using the included GNU regex instead.)
gnupg_cv_included_regex=yes
fi
fi
if test $gnupg_cv_included_regex = yes; then
AC_DEFINE(USE_GNU_REGEX,1,[ Define if you want to use the included regex lib ])
AC_SUBST(REGEX_O,regex.o)
fi
else
AC_DEFINE(DISABLE_REGEX,1,[ Define to disable regular expression support ])
fi
dnl Do we have zlib? Must do it here because Solaris failed
dnl when compiling a conftest (due to the "-lz" from LIBS).
use_local_zlib=yes
if test "$g10_force_zlib" = "yes"; then
:
else
_cppflags="${CPPFLAGS}"
_ldflags="${LDFLAGS}"
AC_ARG_WITH(zlib,
[ --with-zlib=DIR use libz in DIR],[
if test -d "$withval"; then
CPPFLAGS="${CPPFLAGS} -I$withval/include"
LDFLAGS="${LDFLAGS} -L$withval/lib"
fi
])
AC_CHECK_HEADER(zlib.h,
AC_CHECK_LIB(z, deflateInit2_,
use_local_zlib=no
LIBS="$LIBS -lz",
CPPFLAGS=${_cppflags} LDFLAGS=${_ldflags}),
CPPFLAGS=${_cppflags} LDFLAGS=${_ldflags})
fi
if test "$use_local_zlib" = yes ; then
AM_CONDITIONAL(ENABLE_LOCAL_ZLIB, true)
AC_CONFIG_LINKS(zlib.h:zlib/zlib.h zconf.h:zlib/zconf.h )
ZLIBS="../zlib/libzlib.a"
else
AM_CONDITIONAL(ENABLE_LOCAL_ZLIB, false)
ZLIBS=
fi
AC_SUBST(ZLIBS)
+
+# See wether we want to run the long test suite.
+AC_ARG_WITH(pkits-tests,
+ AC_HELP_STRING([--with-pkits-tests],[run the PKITS based tests]),
+ [run_pkits_tests=$withval], [run_pkits_tests=no])
+AM_CONDITIONAL(RUN_PKITS_TESTS, test "$run_pkits_tests" = "yes")
+
+
# Allow users to append something to the version string without
# flagging it as development version. The user version parts is
# considered everything after a dash.
if test "$development_version" != yes; then
changequote(,)dnl
tmp_pat='[a-zA-Z]'
changequote([,])dnl
if echo "$VERSION" | sed 's/-.*//' | grep "$tmp_pat" >/dev/null ; then
development_version=yes
fi
fi
if test "$development_version" = yes; then
AC_DEFINE(IS_DEVELOPMENT_VERSION,1,
[Defined if this is not a regular release])
fi
AM_CONDITIONAL(CROSS_COMPILING, test x$cross_compiling = xyes)
GNUPG_CHECK_GNUMAKE
# add some extra libs here so that previous tests don't fail for
# mysterious reasons - the final link step should bail out.
case "${target}" in
*-*-mingw32*)
W32LIBS="-lwsock32"
;;
*)
;;
esac
if test "$GCC" = yes; then
if test "$USE_MAINTAINER_MODE" = "yes"; then
CFLAGS="$CFLAGS -Wall -Wcast-align -Wshadow -Wstrict-prototypes"
CFLAGS="$CFLAGS -Wformat-nonliteral"
else
CFLAGS="$CFLAGS -Wall"
fi
fi
AC_SUBST(NETLIBS)
AC_SUBST(W32LIBS)
# We use jnlib, so tell other modules about it
AC_DEFINE(HAVE_JNLIB_LOGGING, 1,
[Defined if jnlib style logging functions are available])
#
# Decide what to build
#
missing_pth=no
if test $have_ksba = no; then
build_gpgsm=no
build_scdaemon=no
fi
build_agent_threaded=""
if test "$build_agent" = "yes"; then
if test $have_pth = no; then
build_agent_threaded="(not multi-threaded)"
missing_pth=yes
fi
fi
build_scdaemon_extra=""
if test "$build_scdaemon" = "yes"; then
tmp=""
if test $have_pth = no; then
build_scdaemon_extra="not multi-threaded"
tmp=", "
missing_pth=yes
fi
if test $have_opensc = no; then
build_scdaemon_extra="${build_scdaemon_extra}${tmp}no pkcs#15"
tmp=", "
fi
if test -n "$build_scdaemon_extra"; then
build_scdaemon_extra="(${build_scdaemon_extra})"
fi
fi
if test "$build_agent_only" = "yes" ; then
build_gpg=no
build_gpgsm=no
build_scdaemon=no
fi
AM_CONDITIONAL(BUILD_GPG, test "$build_gpg" = "yes")
AM_CONDITIONAL(BUILD_GPGSM, test "$build_gpgsm" = "yes")
AM_CONDITIONAL(BUILD_AGENT, test "$build_agent" = "yes")
AM_CONDITIONAL(BUILD_SCDAEMON, test "$build_scdaemon" = "yes")
#
# Print errors here so that they are visible all
# together and the user can acquire them all together.
#
die=no
if test "$have_gpg_error" = "no"; then
die=yes
AC_MSG_NOTICE([[
***
*** You need libgpg-error to build this program.
** This library is for example available at
*** ftp://ftp.gnupg.org/gcrypt/alpha/libgpg-error
*** (at least version $NEED_GPG_ERROR_VERSION is required.)
***]])
fi
if test "$have_libgcrypt" = "no"; then
die=yes
AC_MSG_NOTICE([[
***
*** You need libgcrypt to build this program.
** This library is for example available at
*** ftp://ftp.gnupg.org/gcrypt/alpha/libgcrypt/
*** (at least version $NEED_LIBGCRYPT_VERSION using API $NEED_LIBGCRYPT_API) is required.)
***]])
fi
if test "$have_libassuan" = "no"; then
die=yes
AC_MSG_NOTICE([[
***
*** You need libassuan to build this program.
*** This library is for example available at
*** ftp://ftp.gnupg.org/gcrypt/alpha/libassuan/
*** (at least version $NEED_LIBASSUAN_VERSION is required).
***]])
fi
if test "$have_ksba" = "no"; then
AC_MSG_NOTICE([[
***
*** You need libksba to build this program.
*** This library is for example available at
*** ftp://ftp.gnupg.org/gcrypt/alpha/libksba/
*** (at least version $NEED_KSBA_VERSION is required).
***]])
fi
if test "$missing_pth" = "yes"; then
AC_MSG_NOTICE([[
***
*** It is strongly suggested to build with support for the
*** GNU Portable Threads Library (Pth). Please install this
*** library first or use --disable-threads to allow building
*** anyway. The library is for example available at
*** ftp://ftp.gnu.org/gnu/pth/
*** On a Debian GNU/Linux system you can install it using
*** apt-get install libpth-dev
***]])
if test "$enable_threads" != "no"; then
die=yes
fi
fi
if test "$die" = "yes"; then
AC_MSG_ERROR([[
***
*** Required libraries not found. Please consult the above messages
*** and install them before running configure again.
***]])
fi
AC_CONFIG_FILES([ m4/Makefile
Makefile
po/Makefile.in
intl/Makefile
jnlib/Makefile
common/Makefile
kbx/Makefile
g10/Makefile
sm/Makefile
agent/Makefile
scd/Makefile
tools/Makefile
doc/Makefile
tests/Makefile
+tests/pkits/Makefile
])
AC_OUTPUT
echo "
GnuPG v${VERSION} has been configured as follows:
Platform: $PRINTABLE_OS_NAME ($target)
OpenPGP: $build_gpg
S/MIME: $build_gpgsm
Agent: $build_agent $build_agent_threaded
Smartcard: $build_scdaemon $build_scdaemon_extra
- Protect tool: $show_gnupg_protect_tool_pgm
- Default agent: $show_gnupg_agent_pgm
- Default pinentry: $show_gnupg_pinentry_pgm
- Default scdaemon: $show_gnupg_scdaemon_pgm
- Default dirmngr: $show_gnupg_dirmngr_pgm
+ Protect tool: $show_gnupg_protect_tool_pgm
+ Default agent: $show_gnupg_agent_pgm
+ Default pinentry: $show_gnupg_pinentry_pgm
+ Default scdaemon: $show_gnupg_scdaemon_pgm
+ Default dirmngr: $show_gnupg_dirmngr_pgm
+
+ PKITS based tests: $run_pkits_tests
"
diff --git a/doc/gpgsm.texi b/doc/gpgsm.texi
index 2f1033e3f..c79622342 100644
--- a/doc/gpgsm.texi
+++ b/doc/gpgsm.texi
@@ -1,855 +1,867 @@
@c Copyright (C) 2002 Free Software Foundation, Inc.
@c This is part of the GnuPG manual.
@c For copying conditions, see the file gnupg.texi.
@node Invoking GPGSM
@chapter Invoking GPGSM
@cindex GPGSM command options
@cindex command options
@cindex options, GPGSM command
@c man begin DESCRIPTION
@sc{gpgsm} is a tool similar to @sc{gpg} to provide digital encryption
and signing servicesd on X.509 certificates and the CMS protocoll. It
is mainly used as a backend for S/MIME mail processing. @sc{gpgsm}
includes a full features certificate management and complies with all
rules defined for the German Sphinx project.
@c man end
@xref{Option Index}, for an index to GPGSM's commands and options.
@menu
* GPGSM Commands:: List of all commands.
* GPGSM Options:: List of all options.
* GPGSM Examples:: Some usage examples.
Developer information:
* Unattended Usage:: Using @sc{gpgsm} from other programs.
* GPGSM Protocol:: The protocol the server mode uses.
@end menu
@c man begin COMMANDS
@node GPGSM Commands
@section Commands
Commands are not distinguished from options execpt for the fact that
only one one command is allowed.
@menu
* General Commands:: Commands not specific to the functionality.
* Operational Commands:: Commands to select the type of operation.
* Certificate Management:: How to manage certificates.
@end menu
@node General Commands
@subsection Commands not specific to the function
@table @gnupgtabopt
@item --version
@opindex version
Print the program version and licensing information. Not that you can
abbreviate this command.
@item --help, -h
@opindex help
Print a usage message summarizing the most usefule command-line options.
Not that you can abbreviate this command.
@item --dump-options
@opindex dump-options
Print a list of all available options and commands. Not that you can
abbreviate this command.
@end table
@node Operational Commands
@subsection Commands to select the type of operation
@table @gnupgtabopt
@item --encrypt
@opindex encrypt
Perform an encryption.
@item --decrypt
@opindex decrypt
Perform a decryption; the type of input is automatically detmerined. It
may either be in binary form or PEM encoded; automatic determination of
base-64 encoding is not done.
@item --sign
@opindex sign
Create a digital signature. The key used is either the fist one found
in the keybox or thise set with the -u option
@item --verify
@opindex verify
Check a signature file for validity. Depending on the arguments a
detached signatrue may also be checked.
@item --server
@opindex server
Run in server mode and wait for commands on the @code{stdin}.
@item --call-dirmngr @var{command} [@var{args}]
@opindex call-dirmngr
Behave as a Dirmngr client issuing the request @var{command} with the
optional list of @var{args}. The output of the Dirmngr is printed
stdout. Please note that file names given as arguments should have an
absulte file name (i.e. commencing with @code{/} because they are
passed verbatim to the Dirmngr and the working directory of the
Dirmngr might not be the same as the one of this client. Currently it
is not possible to pass data via stdin to the Dirmngr. @var{command}
should not contain spaces.
This is command is required for certain maintaining tasks of the dirmngr
where a dirmngr must be able to call back to gpgsm. See the Dirmngr
manual for details.
@item --call-protect-tool @var{arguments}
@opindex call-protect-tool
Certain maintenance operations are done by an external program call
@command{gpg-protect-tool}; this is usually not installed in a directory
listed in the PATH variable. This command provides a simple wrapper to
access this tool. @var{arguments} are passed verbatim to this command;
use @samp{--help} to get a list of supported operations.
@end table
@node Certificate Management
@subsection How to manage the certificate and keys
@table @gnupgtabopt
@item --gen-key
@opindex gen-key
Generate a new key and a certificate request.
@item --list-keys
@itemx -k
@opindex list-keys
List all available certificates stored in the local key database.
@item --list-secret-keys
@itemx -K
@opindex list-secret-keys
List all available certificates for which a corresponding a secret key
is available.
@item --list-external-keys @var{pattern}
@opindex list-keys
List certificates matching @var{pattern} using an external server. This
utilizes the @code{dirmngr} service.
@item --dump-keys
@opindex dump-keys
List all available certificates stored in the local key database using a
format useful mainly for debugging.
@item --dump-secret-keys
@opindex dump-secret-keys
List all available certificates for which a corresponding a secret key
is available using a format useful mainly for debugging.
@item --dump-external-keys @var{pattern}
@opindex dump-keys
List certificates matching @var{pattern} using an external server.
This utilizes the @code{dirmngr} service. It uses a format useful
mainly for debugging.
@item --keydb-clear-some-cert-flags
@opindex keydb-clear-some-cert-flags
This is a debugging aid to reset certain flags in the key database
which are used to cache certain certificate stati. It is especially
useful if a bad CRL or a weird running OCSP reponder did accidently
revoke certificate. There is no security issue with this command
because gpgsm always make sure that the validity of a certificate is
checked right before it is used.
@item --delete-keys @var{pattern}
@opindex delete-keys
Delete the keys matching @var{pattern}.
@item --export [@var{pattern}]
@opindex export
Export all certificates stored in the Keybox or those specified by the
optional @var{pattern}. When using along with the @code{--armor} option
a few informational lines are prepended before each block.
@item --export-secret-key-p12 @var{key-id}
@opindex export
Export the private key and the certificate identified by @var{key-id}
in a PKCS#12 format. When using along with the @code{--armor} option
a few informational lines are prepended to the output. Note, that the
PKCS#12 format is higly insecure and this command is only provided if
there is no other way to exchange the private key.
@item --learn-card
@opindex learn-card
Read information about the private keys from the smartcard and import
the certificates from there. This command utilizes the @sc{gpg-agent}
and in turn the @sc{scdaemon}.
@item --passwd @var{user_id}
@opindex passwd
Change the passphrase of the private key belonging to the certificate
specified as @var{user_id}. Note, that changing the passphrase/PIN of a
smartcard is not yet supported.
@end table
@node GPGSM Options
@section Option Summary
GPGSM comes features a bunch ofoptions to control the exact behaviour
and to change the default configuration.
@menu
* Configuration Options:: How to change the configuration.
* Certificate Options:: Certificate related options.
* Input and Output:: Input and Output.
* CMS Options:: How to change how the CMS is created.
* Esoteric Options:: Doing things one usually don't want to do.
@end menu
@c man begin OPTIONS
@node Configuration Options
@subsection How to change the configuration
These options are used to change the configuraton and are usually found
in the option file.
@table @gnupgtabopt
@item --options @var{file}
@opindex options
Reads configuration from @var{file} instead of from the default
per-user configuration file. The default configuration file is named
@file{gpgsm.conf} and expected in the @file{.gnupg} directory directly
below the home directory of the user.
@item -v
@item --verbose
@opindex v
@opindex verbose
Outputs additional information while running.
You can increase the verbosity by giving several
verbose commands to @sc{gpgsm}, such as @samp{-vv}.
@item --policy-file @var{filename}
@opindex policy-file
Change the default name of the policy file to @var{filename}.
@item --agent-program @var{file}
@opindex agent-program
Specify an agent program to be used for secret key operations. The
default value is the @file{/usr/local/bin/gpg-agent}. This is only used
as a fallback when the envrionment variable @code{GPG_AGENT_INFO} is not
set or a running agent can't be connected.
@item --dirmngr-program @var{file}
@opindex dirmnr-program
Specify a dirmngr program to be used for @acronym{CRL} checks. The
default value is @file{/usr/sbin/dirmngr}. This is only used as a
fallback when the environment variable @code{DIRMNGR_INFO} is not set or
a running dirmngr can't be connected.
@item --no-secmem-warning
@opindex no-secmem-warning
Don't print a warning when the so called "secure memory" can't be used.
@end table
@node Certificate Options
@subsection Certificate related options
@table @gnupgtabopt
@item --enable-policy-checks
@itemx --disable-policy-checks
@opindex enable-policy-checks
@opindex disable-policy-checks
By default policy checks are enabled. These options may be used to
change it.
@item --enable-crl-checks
@itemx --disable-crl-checks
@opindex enable-crl-checks
@opindex disable-crl-checks
By default the @acronym{CRL} checks are enabled and the DirMngr is used
to check for revoked certificates. The disable option is most useful
with an off-line network connection to suppress this check.
@item --force-crl-refresh
@opindex force-crl-refresh
Tell the dirmngr to reload the CRL for each request. For better
performance, the dirmngr will actually optimize this by suppressing
the loading for short time intervalls (e.g. 30 minutes). This option
is useful to make sure that a fresh CRL is available for certificates
hold in the keybox. The suggested way of doing this is by using it
along with the option @option{--with-validation} for a ke listing
command. This option should not be used in a configuration file.
@item --enable-ocsp
@itemx --disable-ocsp
@opindex enable-ocsp
@opindex disable-ocsp
Be default @acronym{OCSP} checks are disabled. The enable opton may
be used to enable OCSP checks via Dirmngr. If @acronym{CRL} checks
are also enabled, CRLs will be used as a fallback if for some reason an
OCSP request won't succeed. Note, that you have to allow OCSP
requests in Dirmngr's configuration too (option
@option{--allow-ocsp} and configure dirmngr properly. If you don't do
so you will get the error code @samp{Not supported}.
@end table
@node Input and Output
@subsection Input and Output
@table @gnupgtabopt
@item --armor
@itemx -a
@opindex armor
@opindex -a
Create PEM encoded output. Default is binary output.
@item --base64
@opindex base64
Create Base-64 encoded output; i.e. PEM without the header lines.
@item --assume-armor
@opindex assume-armor
Assume the input data is PEM encoded. Default is to autodetect the
encoding but this is may fail.
@item --assume-base64
@opindex assume-base64
Assume the input data is plain base-64 encoded.
@item --assume-binary
@opindex assume-binary
Assume the input data is binary encoded.
@item --local-user @var{user_id}
@item -u @var{user_id}
@opindex local-user
@opindex -u
Set the user(s) to be used for signing. The default is the first
secret key found in the database.
@item --with-key-data
@opindex with-key-data
Displays extra information with the @code{--list-keys} commands. Especially
a line tagged @code{grp} is printed which tells you the keygrip of a
key. This string is for example used as the file name of the
secret key.
@item --with-validation
@opindex with-validation
When doing a key listing, do a full validation check for each key and
print the result. This is usually a slow operation because it
-requires a CRL lookup and other operations.
+requires a CRL lookup and other operations.
+
+When used along with --import, a validation of the certificate to
+import is done and only imported if it succeeds the test. Note that
+this does not affect an already available cwertificate in the DB.
+This option is therefore useful to simply verify a certificate.
+
@item --with-md5-fingerprint
For standard key listings, also print the MD5 fingerprint of the
certificate.
@end table
@node CMS Options
@subsection How to change how the CMS is created.
@table @gnupgtabopt
@item --include-certs @var{n}
Using @var{n} of -2 includes all certificate except for the root cert,
-1 includes all certs, 0 does not include any certs, 1 includes only
the signers cert (this is the default) and all other positive
values include up to @var{n} certificates starting with the signer cert.
@end table
@node Esoteric Options
@subsection Doing things one usually don't want to do.
@table @gnupgtabopt
@item --faked-system-time @var{epoch}
@opindex faked-system-time
This option is only useful for testing; it sets the system time back or
forth to @var{epoch} which is the number of seconds elapsed since the year
1970.
@item --with-ephemeral-keys
@opindex with-ephemeral-keys
Include ephemeral flagged keys in the output of key listings.
@item --debug-level @var{level}
@opindex debug-level
Select the debug level for investigating problems. @var{level} may be
one of:
@table @code
@item none
no debugging at all.
@item basic
some basic debug messages
@item advanced
more verbose debug messages
@item expert
even more detailed messages
@item guru
all of the debug messages you can get
@end table
How these messages are mapped to the actual debugging flags is not
specified and may change with newer releaes of this program. They are
however carefully selected to best aid in debugging.
@item --debug @var{flags}
@opindex debug
This option is only useful for debugging and the behaviour may change
at any time without notice; using @code{--debug-levels} is the
preferred method to select the debug verbosity. FLAGS are bit encoded
and may be given in usual C-Syntax. The currently defined bits are:
@table @code
@item 0 (1)
X.509 or OpenPGP protocol related data
@item 1 (2)
values of big number integers
@item 2 (4)
low level crypto operations
@item 5 (32)
memory allocation
@item 6 (64)
caching
@item 7 (128)
show memory statistics.
@item 9 (512)
write hashed data to files named @code{dbgmd-000*}
@item 10 (1024)
trace Assuan protocol
@end table
Note, that all flags set using this option may get overriden by
@code{--debug-level}.
@item --debug-all
@opindex debug-all
Same as @code{--debug=0xffffffff}
@item --debug-allow-core-dump
@opindex debug-allow-core-dump
Usually gpgsm tries to avoid dumping core by well written code and by
disabling core dumps for security reasons. However, bugs are pretty
durable beasts and to squash them it is sometimes useful to have a core
dump. This option enables core dumps unless the Bad Thing happened
before the option parsing.
@item --debug-no-chain-validation
@opindex debug-no-chain-validation
This is actually not a debugging option but only useful as such. It
lets gpgsm bypass all certificate chain validation checks.
@item --debug-ignore-expiration
@opindex debug-ignore-expiration
This is actually not a debugging option but only useful as such. It
lets gpgsm ignore all notAfter dates, this is used by the regresssion
tests.
+@item --fixed-passphrase @var{string}
+@opindex fixed-passphrase
+Supply the passphrase @var{string} to the gpg-protect-tool. This
+option is only useful for the regression tests included with this
+package and may be revised or removed at any time without notice.
+
@end table
All the long options may also be given in the configuration file after
stripping off the two leading dashes.
@c
@c Examples
@c
@node GPGSM Examples
@section Examples
@c man begin EXAMPLES
@example
$ gpgsm -er goo@@bar.net <plaintext >ciphertext
@end example
@c man end
@c ---------------------------------
@c The machine interface
@c --------------------------------
@node Unattended Usage
@section Unattended Usage
@sc{gpgsm} is often used as a backend engine by other software. To help
with this a machine interface has been defined to have an unambiguous
way to do this. This is most likely used with the @code{--server} command
but may also be used in the standard operation mode by using the
@code{--status-fd} option.
@menu
* Automated signature checking:: Automated signature checking.
@end menu
@node Automated signature checking,,,Unattended Usage
@section Automated signature checking
It is very important to understand the semantics used with signature
verification. Checking a signature is not as simple as it may sound and
so the ooperation si a bit complicated. In mosted cases it is required
to look at several status lines. Here is a table of all cases a signed
message may have:
@table @asis
@item The signature is valid
This does mean that the signature has been successfully verified, the
certificates are all sane. However there are two subcases with
important information: One of the certificates may have expired or a
signature of a message itself as expired. It is a sound practise to
consider such a signature still as valid but additional information
should be displayed. Depending on the subcase @sc{gpgsm} will issue
these status codes:
@table @asis
@item signature valid and nothing did expire
@code{GOODSIG}, @code{VALIDSIG}, @code{TRUST_FULLY}
@item signature valid but at least one certificate has expired
@code{EXPKEYSIG}, @code{VALIDSIG}, @code{TRUST_FULLY}
@item signature valid but expired
@code{EXPSIG}, @code{VALIDSIG}, @code{TRUST_FULLY}
Note, that this case is currently not implemented.
@end table
@item The signature is invalid
This means that the signature verification failed (this is an indication
of af a transfer error, a programm error or tampering with the message).
@sc{gpgsm} issues one of these status codes sequences:
@table @code
@item @code{BADSIG}
@item @code{GOODSIG}, @code{VALIDSIG} @code{TRUST_NEVER}
@end table
@item Error verifying a signature
For some reason the signature could not be verified, i.e. it can't be
decided whether the signature is valid or invalid. A common reason for
this is a missing certificate.
@end table
@c
@c Assuan Protocol
@c
@node GPGSM Protocol
@section The Protocol the Server Mode Uses.
Description of the protocol used to access GPGSM. GPGSM does implement
the Assuan protocol and in addition provides a regular command line
interface which exhibits a full client to this protocol (but uses
internal linking). To start gpgsm as a server the commandline "gpgsm
--server" must be used. Additional options are provided to select the
communication method (i.e. the name of the socket).
We assume that the connection has already been established; see the
Assuan manual for details.
@menu
* GPGSM ENCRYPT:: Encrypting a message.
* GPGSM DECRYPT:: Decrypting a message.
* GPGSM SIGN:: Signing a message.
* GPGSM VERIFY:: Verifying a message.
* GPGSM GENKEY:: Generating a key.
* GPGSM LISTKEYS:: List available keys.
* GPGSM EXPORT:: Export certificates.
* GPGSM IMPORT:: Import certificates.
* GPGSM DELETE:: Delete certificates.
@end menu
@node GPGSM ENCRYPT
@subsection Encrypting a Message
Before encrytion can be done the recipient must be set using the
command:
@example
RECIPIENT @var{userID}
@end example
Set the recipient for the encryption. @var{userID} should be the
internal representation of the key; the server may accept any other way
of specification. If this is a valid and trusted recipient the server
does respond with OK, otherwise the return is an ERR with the reason why
the recipient can't be used, the encryption will then not be done for
this recipient. If the policy is not to encrypt at all if not all
recipients are valid, the client has to take care of this. All
@code{RECIPIENT} commands are cumulative until a @code{RESET} or an
successful @code{ENCRYPT} command.
@example
INPUT FD=@var{n} [--armor|--base64|--binary]
@end example
Set the file descriptor for the message to be encrypted to @var{n}.
Obviously the pipe must be open at that point, the server establishes
its own end. If the server returns an error the client should consider
this session failed.
The @code{--armor} option may be used to advice the server that the
input data is in @acronym{PEM} format, @code{--base64} advices that a
raw base-64 encoding is used, @code{--binary} advices of raw binary
input (@acronym{BER}). If none of these options is used, the server
tries to figure out the used encoding, but this may not always be
correct.
@example
OUTPUT FD=@var{n} [--armor|--base64]
@end example
Set the file descriptor to be used for the output (i.e. the encrypted
message). Obviously the pipe must be open at that point, the server
establishes its own end. If the server returns an error he client
should consider this session failed.
The option armor encodes the output in @acronym{PEM} format, the
@code{--base64} option applies just a base 64 encoding. No option
creates binary output (@acronym{BER}).
The actual encryption is done using the command
@example
ENCRYPT
@end example
It takes the plaintext from the @code{INPUT} command, writes to the
ciphertext to the file descriptor set with the @code{OUTPUT} command,
take the recipients from all the recipients set so far. If this command
fails the clients should try to delete all output currently done or
otherwise mark it as invalid. GPGSM does ensure that there won't be any
security problem with leftover data on the output in this case.
This command should in general not fail, as all necessary checks have
been done while setting the recipients. The input and output pipes are
closed.
@node GPGSM DECRYPT
@subsection Decrypting a message
Input and output FDs are set the same way as in encryption, but
@code{INPUT} refers to the ciphertext and output to the plaintext. There
is no need to set recipients. GPGSM automatically strips any
@acronym{S/MIME} headers from the input, so it is valid to pass an
entire MIME part to the INPUT pipe.
The encryption is done by using the command
@example
DECRYPT
@end example
It performs the decrypt operation after doing some check on the internal
state. (e.g. that all needed data has been set). Because it utilizes
the GPG-Agent for the session key decryption, there is no need to ask
the client for a protecting passphrase - GpgAgent takes care of this by
requesting this from the user.
@node GPGSM SIGN
@subsection Signing a Message
Signing is usually done with these commands:
@example
INPUT FD=@var{n} [--armor|--base64|--binary]
@end example
This tells GPGSM to read the data to sign from file descriptor @var{n}.
@example
OUTPUT FD=@var{m} [--armor|--base64]
@end example
Write the output to file descriptor @var{m}. If a detached signature is
requested, only the signature is written.
@example
SIGN [--detached]
@end example
Sign the data set with the INPUT command and write it to the sink set by
OUTPUT. With @code{--detached}, a detached signature is created
(surprise).
The key used for signining is the default one or the one specified in
the configuration file. To get finer control over the keys, it is
possible to use the command
@example
SIGNER @var{userID}
@end example
to the signer's key. @var{userID} should be the
internal representation of the key; the server may accept any other way
of specification. If this is a valid and trusted recipient the server
does respond with OK, otherwise the return is an ERR with the reason why
the key can't be used, the signature will then not be created using
this key. If the policy is not to sign at all if not all
keys are valid, the client has to take care of this. All
@code{SIGNER} commands are cumulative until a @code{RESET} is done.
Note that a @code{SIGN} does not reset this list of signers which is in
contrats to the @code{RECIPIENT} command.
@node GPGSM VERIFY
@subsection Verifying a Message
To verify a mesage the command:
@example
VERIFY
@end example
is used. It does a verify operation on the message send to the input FD.
The result is written out using status lines. If an output FD was
given, the signed text will be written to that. If the signature is a
detached one, the server will inquire about the signed material and the
client must provide it.
@node GPGSM GENKEY
@subsection Generating a Key
This is used to generate a new keypair, store the secret part in the
@acronym{PSE} and the public key in the key database. We will probably
add optional commands to allow the client to select whether a hardware
token is used to store the key. Configuration options to GPGSM can be
used to restrict the use of this command.
@example
GENKEY
@end example
GPGSM checks whether this command is allowed and then does an
INQUIRY to get the key parameters, the client should then send the
key parameters in the native format:
@example
S: INQUIRE KEY_PARAM native
C: D foo:fgfgfg
C: D bar
C: END
@end example
Please note that the server may send Status info lines while reading the
data lines from the client. After this the key generation takes place
and the server eventually does send an ERR or OK response. Status lines
may be issued as a progress indicator.
@node GPGSM LISTKEYS
@subsection List available keys
To list the keys in the internal database or using an external key
provider, the command:
@example
LISTKEYS @var{pattern}
@end example
is used. To allow multiple patterns (which are ORed during the search)
quoting is required: Spaces are to be translated into "+" or into "%20";
in turn this requires that the usual escape quoting rules are done.
@example
LISTSECRETKEYS @var{pattern}
@end example
Lists only the keys where a secret key is available.
The list commands commands are affected by the option
@example
OPTION list-mode=@var{mode}
@end example
where mode may be:
@table @code
@item 0
Use default (which is usually the same as 1).
@item 1
List only the internal keys.
@item 2
List only the external keys.
@item 3
List internal and external keys.
@end table
Note that options are valid for the entire session.
@node GPGSM EXPORT
@subsection Export certificates
To export certificate from the internal key database the command:
@example
EXPORT @var{pattern}
@end example
is used. To allow multiple patterns (which are ORed) quoting is
required: Spaces are to be translated into "+" or into "%20"; in turn
this requires that the usual escape quoting rules are done.
The format of the output depends on what was set with the OUTPUT
command. When using @acronym{PEM} encoding a few informational lines
are prepended.
@node GPGSM IMPORT
@subsection Import certificates
To import certificates into the internal key database, the command
@example
IMPORT
@end example
is used. The data is expected on the file descriptor set with the
@code{INPUT} command. Certain checks are performend on the
certificate. Note that the code will also handle PKCS\#12 files and
import private keys; a helper program is used for that.
@node GPGSM DELETE
@subsection Delete certificates
To delete certificate the command
@example
DELKEYS @var{pattern}
@end example
is used. To allow multiple patterns (which are ORed) quoting is
required: Spaces are to be translated into "+" or into "%20"; in turn
this requires that the usual escape quoting rules are done.
The certificates must be specified unambiguously otherwise an error is
returned.
diff --git a/po/de.po b/po/de.po
index 4dbe66e8a..06ae4320e 100644
--- a/po/de.po
+++ b/po/de.po
@@ -1,1225 +1,1225 @@
# German translation for GnuPG 1.9.x
# Copyright (C) 2002, 2004 Free Software Foundation, Inc.
# Werner Koch <wk@gnupg.org>, 2002.
#
#
# Note that we use "gnupg2" as the domain to avoid conflicts with
# already installed domains "gnupg" from GnuPG < 1.9.
#
msgid ""
msgstr ""
"Project-Id-Version: gnupg2 1.9.10\n"
"Report-Msgid-Bugs-To: translations@gnupg.org\n"
-"POT-Creation-Date: 2004-07-22 09:54+0200\n"
+"POT-Creation-Date: 2004-08-05 11:31+0200\n"
"PO-Revision-Date: 2004-07-22 10:05+0200\n"
"Last-Translator: Werner Koch <wk@gnupg.org>\n"
"Language-Team: de\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=iso-8859-1\n"
"Content-Transfer-Encoding: 8bit\n"
-#: agent/gpg-agent.c:96 agent/protect-tool.c:94 scd/scdaemon.c:92
+#: agent/gpg-agent.c:96 agent/protect-tool.c:94 scd/scdaemon.c:93
msgid ""
"@Options:\n"
" "
msgstr ""
"@Optionen:\n"
" "
-#: agent/gpg-agent.c:98 scd/scdaemon.c:94
+#: agent/gpg-agent.c:98 scd/scdaemon.c:95
msgid "run in server mode (foreground)"
msgstr "Im Server Modus ausführen"
-#: agent/gpg-agent.c:99 scd/scdaemon.c:95
+#: agent/gpg-agent.c:99 scd/scdaemon.c:96
msgid "run in daemon mode (background)"
msgstr "Im Daemon Modus ausführen"
-#: agent/gpg-agent.c:100 kbx/kbxutil.c:75 scd/scdaemon.c:96 sm/gpgsm.c:313
+#: agent/gpg-agent.c:100 kbx/kbxutil.c:75 scd/scdaemon.c:97 sm/gpgsm.c:313
#: tools/gpgconf.c:62
msgid "verbose"
msgstr "ausführlich"
-#: agent/gpg-agent.c:101 kbx/kbxutil.c:76 scd/scdaemon.c:97 sm/gpgsm.c:314
+#: agent/gpg-agent.c:101 kbx/kbxutil.c:76 scd/scdaemon.c:98 sm/gpgsm.c:314
msgid "be somewhat more quiet"
msgstr "etwas weniger Aussageb erzeugen"
-#: agent/gpg-agent.c:102 scd/scdaemon.c:98
+#: agent/gpg-agent.c:102 scd/scdaemon.c:99
msgid "sh-style command output"
msgstr "Ausgabe für /bin/sh"
-#: agent/gpg-agent.c:103 scd/scdaemon.c:99
+#: agent/gpg-agent.c:103 scd/scdaemon.c:100
msgid "csh-style command output"
msgstr "Ausgabe für /bin/csh"
#: agent/gpg-agent.c:104
msgid "|FILE|read options from FILE"
msgstr "|DATEI|Konfigurationsoptionen aus DATEI lesen"
-#: agent/gpg-agent.c:109 scd/scdaemon.c:106
+#: agent/gpg-agent.c:109 scd/scdaemon.c:107
msgid "do not detach from the console"
msgstr "Im Vordergrund laufen lassen"
#: agent/gpg-agent.c:110
msgid "do not grab keyboard and mouse"
msgstr "Tastatur und Maus nicht \"grabben\""
-#: agent/gpg-agent.c:111 scd/scdaemon.c:107 sm/gpgsm.c:316
+#: agent/gpg-agent.c:111 scd/scdaemon.c:108 sm/gpgsm.c:316
msgid "use a log file for the server"
msgstr "Logausgaben in eine Datei umlenken"
#: agent/gpg-agent.c:112
msgid "do not allow multiple connections"
msgstr "Nicht mehr als eine Verbindung erlauben"
#: agent/gpg-agent.c:115
msgid "|PGM|use PGM as the PIN-Entry program"
msgstr "|PGM|benutze PGM as PIN-Entry"
#: agent/gpg-agent.c:117
msgid "|PGM|use PGM as the SCdaemon program"
msgstr "|PGM|benutze PGM as SCdaemon"
#: agent/gpg-agent.c:124
msgid "ignore requests to change the TTY"
msgstr "Ignoriere Anfragen, das TTY zu wechseln"
#: agent/gpg-agent.c:126
msgid "ignore requests to change the X display"
msgstr "Ignoriere Anfragen, das X-Display zu wechseln"
#: agent/gpg-agent.c:129
msgid "|N|expire cached PINs after N seconds"
msgstr "|N|lasse PINs im Cache nach N Sekunden verfallen"
#: agent/gpg-agent.c:131
msgid "do not use the PIN cache when signing"
msgstr "benutze PINs im Cache nicht bem Signieren"
#: agent/gpg-agent.c:133
msgid "allow clients to mark keys as \"trusted\""
msgstr "erlaube Aufrufern Schlüssel als \"vertrauenswürdig\" zu markieren"
-#: agent/gpg-agent.c:191 agent/protect-tool.c:127 scd/scdaemon.c:165
+#: agent/gpg-agent.c:191 agent/protect-tool.c:127 scd/scdaemon.c:168
#: sm/gpgsm.c:481 tools/gpgconf.c:85
msgid "Please report bugs to <"
msgstr "Fehlerberichte bitte an <"
-#: agent/gpg-agent.c:191 agent/protect-tool.c:127 scd/scdaemon.c:165
+#: agent/gpg-agent.c:191 agent/protect-tool.c:127 scd/scdaemon.c:168
#: sm/gpgsm.c:481 tools/gpgconf.c:85
msgid ">.\n"
msgstr ">.\n"
#: agent/gpg-agent.c:194
msgid "Usage: gpg-agent [options] (-h for help)"
msgstr "Gebrauch: gpg-agent [Optionen] (-h für Hilfe)"
#: agent/gpg-agent.c:196
msgid ""
"Syntax: gpg-agent [options] [command [args]]\n"
"Secret key management for GnuPG\n"
msgstr ""
"Syntax: gpg-agent [Optionen] [Kommando [Argumente]]\n"
"Verwaltung von geheimen Schlüssel für GnuPG\n"
-#: agent/gpg-agent.c:267 scd/scdaemon.c:239 sm/gpgsm.c:604
+#: agent/gpg-agent.c:267 scd/scdaemon.c:242 sm/gpgsm.c:604
#, c-format
msgid "invalid debug-level `%s' given\n"
msgstr "ungültige Debugebene `%s' angegeben\n"
#: agent/gpg-agent.c:439 agent/protect-tool.c:1040 kbx/kbxutil.c:232
-#: scd/scdaemon.c:352 sm/gpgsm.c:726
+#: scd/scdaemon.c:357 sm/gpgsm.c:726
#, c-format
msgid "libgcrypt is too old (need %s, have %s)\n"
msgstr ""
"Die Bibliothek \"libgcrypt\" is zu alt (benötigt wird %s, vorhanden ist %s)\n"
-#: agent/gpg-agent.c:512 scd/scdaemon.c:432 sm/gpgsm.c:824
+#: agent/gpg-agent.c:512 scd/scdaemon.c:437 sm/gpgsm.c:824
#, c-format
msgid "NOTE: no default option file `%s'\n"
msgstr "Notiz: Voreingestellte Konfigurationsdatei `%s' fehlt\n"
-#: agent/gpg-agent.c:517 agent/gpg-agent.c:983 scd/scdaemon.c:437
+#: agent/gpg-agent.c:517 agent/gpg-agent.c:983 scd/scdaemon.c:442
#: sm/gpgsm.c:828
#, c-format
msgid "option file `%s': %s\n"
msgstr "Konfigurationsdatei `%s': %s\n"
-#: agent/gpg-agent.c:525 scd/scdaemon.c:445 sm/gpgsm.c:835
+#: agent/gpg-agent.c:525 scd/scdaemon.c:450 sm/gpgsm.c:835
#, c-format
msgid "reading options from `%s'\n"
msgstr "Optionen werden aus `%s' gelesen\n"
-#: agent/gpg-agent.c:668 scd/scdaemon.c:619
+#: agent/gpg-agent.c:668 scd/scdaemon.c:630
msgid "please use the option `--daemon' to run the program in the background\n"
msgstr ""
"Bitte die Option `--daemon' nutzen um das Programm im Hintergund "
"auszuführen\n"
#: agent/gpg-agent.c:1016 agent/gpg-agent.c:1050
#, c-format
msgid "can't create directory `%s': %s\n"
msgstr "Das Verzeichniss `%s' kann nicht erstell werden: %s\n"
#: agent/gpg-agent.c:1019 agent/gpg-agent.c:1055
#, c-format
msgid "directory `%s' created\n"
msgstr "Verzeichniss `%s' wurde erstellt\n"
#: agent/protect-tool.c:130
msgid "Usage: gpg-protect-tool [options] (-h for help)\n"
msgstr "Gebrauch: gpg-protect-tool [Optionen] (-h für Hilfe)\n"
#: agent/protect-tool.c:132
msgid ""
"Syntax: gpg-protect-tool [options] [args]]\n"
"Secret key maintenance tool\n"
msgstr ""
"Syntax: gpg-protect-tool [Optionen] [Argumente]\n"
"Werkzeug zum Bearbeiten von geheimen Schlüsseln\n"
#: agent/protect-tool.c:1148
msgid ""
"Please enter the passphrase or the PIN\n"
"needed to complete this operation."
msgstr ""
"Die Eingabe des Mantras (Passphrase) bzw. der PIN\n"
"wird benötigt um diese Aktion auszuführen."
#: agent/protect-tool.c:1151
msgid "Passphrase:"
msgstr "Passphrase:"
#: agent/divert-scd.c:200
#, c-format
msgid "Please enter the PIN%s%s%s to unlock the card"
msgstr "Bitte geben Sie die PIN%s%s%s ein um die Karte zu entsperren"
#: agent/genkey.c:108
#, c-format
msgid "Please enter the passphrase to%0Ato protect your new key"
msgstr ""
"Bitte geben Sie das Mantra (Passphrase) ein%0Aum Ihren Schlüssel zu schützen"
#: agent/genkey.c:110 agent/genkey.c:224
msgid "Please re-enter this passphrase"
msgstr "Bitte geben Sie das Mantra (Passphrase) noch einmal ein:"
#: agent/genkey.c:131 agent/genkey.c:244
msgid "does not match - try again"
msgstr "Keine Übereinstimmung - bitte nochmal versuchen"
#: agent/genkey.c:223
msgid "Please enter the new passphrase"
msgstr "Bitte geben Sie das Mantra (Passphrase) ein:"
#: agent/query.c:268
msgid ""
"Please enter your PIN, so that the secret key can be unlocked for this "
"session"
msgstr ""
"Bitte geben Sie Ihre PIN ein, so daß der geheime Schlüssel benutzt werden "
"kann"
#: agent/query.c:271
msgid ""
"Please enter your passphrase, so that the secret key can be unlocked for "
"this session"
msgstr ""
"Bitte geben Sie Ihr Mantra (Passphrase) ein, so daß der geheime Schlüssel "
"benutzt werden kann"
#: agent/query.c:326 agent/query.c:338
msgid "PIN too long"
msgstr "Die PIN ist zu lang"
#: agent/query.c:327
msgid "Passphrase too long"
msgstr "Das Matra (Passphrase) ist zu lang"
#: agent/query.c:335
msgid "Invalid characters in PIN"
msgstr "Ungültige Zeichen in der PIN"
#: agent/query.c:340
msgid "PIN too short"
msgstr "Die PIN ist zu kurz"
#: agent/query.c:352
msgid "Bad PIN"
msgstr "Falsche PIN"
#: agent/query.c:353
msgid "Bad Passphrase"
msgstr "Falsches Mantra (Passphrase)"
#: agent/query.c:392
msgid "Passphrase"
msgstr "Mantra"
#: common/sysutils.c:87
#, c-format
msgid "can't disable core dumps: %s\n"
msgstr ""
"Das Erstellen eines Speicherabzugs (core-dump) kann nicht verhindert werden: "
"%s\n"
#: common/sysutils.c:182
#, c-format
msgid "Warning: unsafe ownership on %s \"%s\"\n"
msgstr "WARNUNG: Unsichere Besitzrechte für %s \"%s\"\n"
#: common/sysutils.c:214
#, c-format
msgid "Warning: unsafe permissions on %s \"%s\"\n"
msgstr "WARNUNG: Unsichere Zugriffsrechte für %s \"%s\"\n"
#: common/simple-pwquery.c:272
msgid "gpg-agent is not available in this session\n"
msgstr "Der gpg-agent ist nicht verfügbar\n"
#: common/simple-pwquery.c:286 sm/call-agent.c:128
msgid "malformed GPG_AGENT_INFO environment variable\n"
msgstr "Die Variable GPG_AGENT_INFO ist fehlerhaft\n"
#: common/simple-pwquery.c:298 sm/call-agent.c:140
#, c-format
msgid "gpg-agent protocol version %d is not supported\n"
msgstr "Das gpg-agent Protocol %d wird nicht unterstützt\n"
#: common/simple-pwquery.c:320
#, c-format
msgid "can't connect to `%s': %s\n"
msgstr "Verbindung zu `%s' kann nicht aufgebaut werden: %s\n"
#: common/simple-pwquery.c:331
msgid "communication problem with gpg-agent\n"
msgstr "Kommunikationsproblem mit gpg-agent\n"
#: common/simple-pwquery.c:341
msgid "problem setting the gpg-agent options\n"
msgstr "Beim setzen der gpg-agent Optionen ist ein problem aufgetreten\n"
#: common/simple-pwquery.c:473
msgid "canceled by user\n"
msgstr "Vom Benutzer abgebrochen\n"
#: common/simple-pwquery.c:480
msgid "problem with the agent\n"
msgstr "Problem mit dem Agenten\n"
#: jnlib/logging.c:555
#, c-format
msgid "you found a bug ... (%s:%d)\n"
msgstr "Sie haben einen Bug (Softwarefehler) gefunden ... (%s:%d)\n"
#: kbx/kbxutil.c:63 sm/gpgsm.c:224 tools/gpgconf.c:53
msgid ""
"@Commands:\n"
" "
msgstr ""
"@Kommandos:\n"
" "
#: kbx/kbxutil.c:70 sm/gpgsm.c:259 tools/gpgconf.c:59
msgid ""
"@\n"
"Options:\n"
" "
msgstr ""
"@\n"
"Optionen:\n"
" "
#: kbx/kbxutil.c:77 sm/gpgsm.c:321 tools/gpgconf.c:64
msgid "do not make any changes"
msgstr "Keine Änderungen durchführen"
#: kbx/kbxutil.c:79
msgid "set debugging flags"
msgstr "Debug Flags setzen"
#: kbx/kbxutil.c:80
msgid "enable full debugging"
msgstr "Alle Debug Flags setzen"
#: kbx/kbxutil.c:101
msgid "Please report bugs to "
msgstr "Bite richten sie Berichte über Bugs (Softwarefehler) an "
#: kbx/kbxutil.c:101
msgid ".\n"
msgstr ".\n"
#: kbx/kbxutil.c:105
msgid "Usage: kbxutil [options] [files] (-h for help)"
msgstr "Gebrauch: kbxutil [Optionen] [Dateien] (-h für Hilfe)"
#: kbx/kbxutil.c:108
msgid ""
"Syntax: kbxutil [options] [files]\n"
"list, export, import Keybox data\n"
msgstr ""
"Syntax: kbxutil [Optionen] [Dateien]\n"
"Anlistem exportieren und Importieren von KeyBox Dateien\n"
-#: scd/scdaemon.c:100 sm/gpgsm.c:333
+#: scd/scdaemon.c:101 sm/gpgsm.c:333
msgid "read options from file"
msgstr "Konfigurationsoptionen aus Datei lesen"
-#: scd/scdaemon.c:105
+#: scd/scdaemon.c:106
msgid "|N|set OpenSC debug level to N"
msgstr "|N|Den OpenSC Debugstufe auf N setzen"
-#: scd/scdaemon.c:108
+#: scd/scdaemon.c:109
msgid "|N|connect to reader at port N"
msgstr "|N|Verbinde mit dem Leser auf Port N"
-#: scd/scdaemon.c:109
+#: scd/scdaemon.c:110
msgid "|NAME|use NAME as ct-API driver"
msgstr "|NAME|Benutze NAME als CT-API Treiber"
-#: scd/scdaemon.c:110
+#: scd/scdaemon.c:111
msgid "|NAME|use NAME as PC/SC driver"
msgstr "|NAME|Benutze NAME als PC/SC Treiber"
-#: scd/scdaemon.c:113
+#: scd/scdaemon.c:114
msgid "do not use the internal CCID driver"
msgstr "Den internen CCID Treiber nicht benutzen"
-#: scd/scdaemon.c:120
+#: scd/scdaemon.c:121
msgid "do not use the OpenSC layer"
msgstr "Den OpenSC basierten Kartenzugriff nicht nutzen"
-#: scd/scdaemon.c:125
+#: scd/scdaemon.c:126
msgid "allow the use of admin card commands"
msgstr "Erlaube die Benuztung von \"Admin\" Kommandos"
-#: scd/scdaemon.c:168
+#: scd/scdaemon.c:171
msgid "Usage: scdaemon [options] (-h for help)"
msgstr "Gebrauch: scdaemon [Optionen] (-h für Hilfe)"
-#: scd/scdaemon.c:170
+#: scd/scdaemon.c:173
msgid ""
"Syntax: scdaemon [options] [command [args]]\n"
"Smartcard daemon for GnuPG\n"
msgstr ""
"Synatx: scdaemon [Optionen] [Kommando [Argumente]]\n"
"Smartcard Daemon für GnuPG\n"
#: sm/base64.c:315
#, c-format
msgid "invalid radix64 character %02x skipped\n"
msgstr "Ungültiges Basis-64 Zeichen %02X wurde übergangen\n"
#: sm/call-agent.c:88
msgid "no running gpg-agent - starting one\n"
msgstr "Kein aktiver gpg-agent - es wird einer gestarted\n"
#: sm/call-agent.c:151
msgid "can't connect to the agent - trying fall back\n"
msgstr "Verbindung zum gpg-agent nicht möglich - Ersatzmethode wird versucht\n"
#: sm/call-dirmngr.c:164
msgid "no running dirmngr - starting one\n"
msgstr "Kein aktiver Dirmngr - es wird einer gestartet\n"
#: sm/call-dirmngr.c:202
msgid "malformed DIRMNGR_INFO environment variable\n"
msgstr "Die Variable DIRMNGR_INFO ist fehlerhaft\n"
#: sm/call-dirmngr.c:214
#, c-format
msgid "dirmngr protocol version %d is not supported\n"
msgstr "Die Dirmngr Protokollversion %d wird nicht unterstützt\n"
#: sm/call-dirmngr.c:225
msgid "can't connect to the dirmngr - trying fall back\n"
msgstr ""
"Verbindung zum Dirmngr kann nicht aufgebaut werden - Ersatzmethode wird "
"versucht\n"
#: sm/certdump.c:59 sm/certdump.c:142
msgid "none"
msgstr "keine"
#: sm/certdump.c:151
msgid "[none]"
msgstr "[keine]"
#: sm/certdump.c:490
msgid "[Error - No name]"
msgstr "[Fehler - Kein Name]"
#: sm/certdump.c:499
msgid "[Error - unknown encoding]"
msgstr "[Fehler - Unbekannte Kodierung]"
#: sm/certdump.c:503
msgid "[Error - invalid encoding]"
msgstr "[Fehler - Ungültige Kodierung]"
#: sm/certdump.c:508
msgid "[Error - invalid DN]"
msgstr "[Fehler - Ungültiger DN]"
#: sm/certdump.c:652
#, c-format
msgid ""
"Please enter the passphrase to unlock the secret key for:\n"
"\"%s\"\n"
"S/N %s, ID %08lX, created %s"
msgstr ""
"Bitte geben Sie die Passphrase an, um den \n"
"geheimen Schlüssels von\n"
"\"%s\"\n"
"S/N %s, ID %08lX, erzeugt %s\n"
"zu entsperren"
#: sm/certlist.c:113
msgid "no key usage specified - assuming all usages\n"
msgstr ""
"Schlüsselverwendungszweck nicht vorhanden - für alle Zwecke akzeptiert\n"
#: sm/certlist.c:123 sm/keylist.c:224
#, c-format
msgid "error getting key usage information: %s\n"
msgstr "Fehler beim holen der Schlüsselbenutzungsinformationen: %s\n"
#: sm/certlist.c:133
msgid "certificate should have not been used for certification\n"
msgstr "Das Zertifikat hätte nicht zum Zertifizieren benutzt werden sollen\n"
#: sm/certlist.c:144
msgid "certificate should have not been used for encryption\n"
msgstr "Das Zertifikat hatte nicht zum Verschlüsseln benutzt werden sollen\n"
#: sm/certlist.c:145
msgid "certificate should have not been used for signing\n"
msgstr "Das Zertifikat hatte nicht zum Signieren benutzt werden sollen\n"
#: sm/certlist.c:146
msgid "certificate is not usable for encryption\n"
msgstr "Das Zertifikat kann nicht zum Verschlüsseln benutzt werden\n"
#: sm/certlist.c:147
msgid "certificate is not usable for signing\n"
msgstr "Das Zertifikat kann nicht zum Signieren benutzt werden\n"
#: sm/certchain.c:109
#, c-format
msgid "critical certificate extension %s is not supported"
msgstr "Die kritische Zertifikaterweiterung %s wird nicht unterstützt"
#: sm/certchain.c:131
msgid "issuer certificate is not marked as a CA"
msgstr "Das Herausgeberzertifikat ist nicht für eine CA gekennzeichnet"
#: sm/certchain.c:169
msgid "critical marked policy without configured policies"
msgstr "kritische Richtlinie ohne konfigurierte Richtlinien"
#: sm/certchain.c:185 sm/certchain.c:214
msgid "note: non-critical certificate policy not allowed"
msgstr "Notiz: Die unkritische Zertifikatrichtlinie ist nicht erlaubt"
#: sm/certchain.c:189 sm/certchain.c:218
msgid "certificate policy not allowed"
msgstr "Die Zertifikatrichtlinie ist nicht erlaubt"
#: sm/certchain.c:349
msgid "looking up issuer at external location\n"
msgstr "Der Herausgeber wird von einer externen Stelle gesucht\n"
#: sm/certchain.c:367
#, c-format
msgid "number of issuers matching: %d\n"
msgstr "Anzahl der übereinstimmenden Heruasgeber: %d\n"
#: sm/certchain.c:403 sm/certchain.c:561 sm/certchain.c:912 sm/decrypt.c:260
#: sm/encrypt.c:341 sm/sign.c:324 sm/verify.c:106
msgid "failed to allocated keyDB handle\n"
msgstr "Ein keyDB Handle konnte nicht bereitgestellt werden\n"
#: sm/certchain.c:492
msgid "certificate has been revoked"
msgstr "Das Zertifikat wurde widerrufen"
#: sm/certchain.c:501
msgid "no CRL found for certificate"
msgstr "Keine CRL für das Zertifikat gefunden"
#: sm/certchain.c:505
msgid "the available CRL is too old"
msgstr "Die vorhandene CRL ist zu alt"
#: sm/certchain.c:507
msgid "please make sure that the \"dirmngr\" is properly installed\n"
msgstr ""
"Bite vergewissern Sie sich das der \"dirmngr\" richtig installierrt ist\n"
#: sm/certchain.c:512
#, c-format
msgid "checking the CRL failed: %s"
msgstr "Die CRL konnte nicht geprüft werden: %s"
#: sm/certchain.c:581
msgid "no issuer found in certificate"
msgstr "Im Zertifikat ist kein Herausgeber enthalten"
#: sm/certchain.c:594
#, c-format
msgid "certificate with invalid validity: %s"
msgstr "Zertifikat mit unzulässiger Gültigkeit: %s"
#: sm/certchain.c:610
msgid "certificate not yet valid"
msgstr "Das Zertifikat ist noch nicht gültig"
#: sm/certchain.c:623
msgid "certificate has expired"
msgstr "Das Zertifikat ist abgelaufen"
#: sm/certchain.c:660
msgid "selfsigned certificate has a BAD signature"
msgstr "Das eigenbeglaubigte Zertifikat hat eine FALSCHE Signatur"
#: sm/certchain.c:674
msgid "root certificate is not marked trusted"
msgstr "Das Wurzelzertifikat ist nicht als vertrauenswürdig markiert"
#: sm/certchain.c:680
#, c-format
msgid "fingerprint=%s\n"
msgstr "Fingerprint=%s\n"
#: sm/certchain.c:685
msgid "root certificate has now been marked as trusted\n"
msgstr "Das Wurzelzertifikat wurde nun als vertrauenswürdig markiert\n"
#: sm/certchain.c:700
#, c-format
msgid "checking the trust list failed: %s\n"
msgstr "Fehler beim Prüfen der vertrauenswürdigen Zertifikate: %s\n"
#: sm/certchain.c:724 sm/import.c:166
msgid "certificate chain too long\n"
msgstr "Der Zertifikatkette ist zu lang\n"
#: sm/certchain.c:736
msgid "issuer certificate not found"
msgstr "Herausgeberzertifikat nicht gefunden"
#: sm/certchain.c:769
msgid "certificate has a BAD signature"
msgstr "Das Zertifikat hat eine FALSCHE Signatur"
#: sm/certchain.c:792
msgid "found another possible matching CA certificate - trying again"
msgstr ""
"Eine anderes möglicherweise passendes CA-Zertifikat gefunden - versuche "
"nochmal"
#: sm/certchain.c:815
#, c-format
msgid "certificate chain longer than allowed by CA (%d)"
msgstr "Die Zertifikatkette ist länger als von der CA erlaubt (%d)"
#: sm/decrypt.c:127
msgid ""
"WARNING: message was encrypted with a weak key in the symmetric cipher.\n"
msgstr ""
"WARNUNG: Die Nachricht wurde mich einem schwachen Schlüssel (Weak Key) "
"erzeugt\n"
#: sm/decrypt.c:325
msgid "(this is the RC2 algorithm)\n"
msgstr "(Dies ist der RC-2 Algorithmus)\n"
#: sm/decrypt.c:327
msgid "(this does not seem to be an encrypted message)\n"
msgstr "(dies is wahrscheinlich keine verschlüsselte Nachricht)\n"
#: sm/delete.c:51 sm/delete.c:102
#, c-format
msgid "certificate `%s' not found: %s\n"
msgstr "Zertifikat `%s' nicht gefunden: %s\n"
#: sm/delete.c:112 sm/keydb.c:1403 sm/keydb.c:1496
#, c-format
msgid "error locking keybox: %s\n"
msgstr "Fehler beim Sperren der Keybox: %s\n"
#: sm/delete.c:133
#, c-format
msgid "duplicated certificate `%s' deleted\n"
msgstr "Doppeltes Zertifikat `%s' gelöscht\n"
#: sm/delete.c:135
#, c-format
msgid "certificate `%s' deleted\n"
msgstr "Zertifikat `%s' gelöscht\n"
#: sm/delete.c:165
#, c-format
msgid "deleting certificate \"%s\" failed: %s\n"
msgstr "Fehler beim Löschen des Zertifikats \"%s\": %s\n"
#: sm/encrypt.c:120
msgid "weak key created - retrying\n"
msgstr "Schwacher Schlüssel - es wird erneut versucht\n"
#: sm/encrypt.c:332
msgid "no valid recipients given\n"
msgstr "Keine gültigen Empfänger angegeben\n"
#: sm/gpgsm.c:226
msgid "|[FILE]|make a signature"
msgstr "|[DATEI]|Erzeuge eine Signatur"
#: sm/gpgsm.c:227
msgid "|[FILE]|make a clear text signature"
msgstr "|[DATEI]|Erzeuge eine Klartextsignatur"
#: sm/gpgsm.c:228
msgid "make a detached signature"
msgstr "Erzeuge eine abgetrennte Signatur"
#: sm/gpgsm.c:229
msgid "encrypt data"
msgstr "Verschlüssele die Daten"
#: sm/gpgsm.c:230
msgid "encryption only with symmetric cipher"
msgstr "Verschlüsselung nur mit symmetrischem Algrithmus"
#: sm/gpgsm.c:231
msgid "decrypt data (default)"
msgstr "Enschlüssele die Daten"
#: sm/gpgsm.c:232
msgid "verify a signature"
msgstr "Überprüfen einer Signatur"
#: sm/gpgsm.c:234
msgid "list keys"
msgstr "Schlüssel anzeigen"
#: sm/gpgsm.c:235
msgid "list external keys"
msgstr "Externe Schlüssel anzeigen"
#: sm/gpgsm.c:236
msgid "list secret keys"
msgstr "Geheime Schlüssel anzeigen"
#: sm/gpgsm.c:237
msgid "list certificate chain"
msgstr "Schlüssel mit Zertifikatekette anzeigen"
#: sm/gpgsm.c:239
msgid "list keys and fingerprints"
msgstr "Schlüssel und Fingerprint anzeigen"
#: sm/gpgsm.c:240
msgid "generate a new key pair"
msgstr "Neues Schlüsselpaar erzeugen"
#: sm/gpgsm.c:241
msgid "remove key from the public keyring"
msgstr "Schlüssel aus dem öffentlichen Schlüsselbund löschen"
#: sm/gpgsm.c:242
msgid "export keys to a key server"
msgstr "Schlüssen an eine Schlüsselserver exportieren"
#: sm/gpgsm.c:243
msgid "import keys from a key server"
msgstr "Schlüssel von einem Schlüsselserver importieren"
#: sm/gpgsm.c:244
msgid "import certificates"
msgstr "Zertifikate importieren"
#: sm/gpgsm.c:245
msgid "export certificates"
msgstr "Zertifikate exportieren"
#: sm/gpgsm.c:246
msgid "register a smartcard"
msgstr "Smartcard registrieren"
#: sm/gpgsm.c:247
msgid "run in server mode"
msgstr "Im Server Modus ausführen"
#: sm/gpgsm.c:248
msgid "pass a command to the dirmngr"
msgstr "Das Kommand an den Dirmngr durchreichen"
#: sm/gpgsm.c:250
msgid "invoke gpg-protect-tool"
msgstr "Rufe das gpg-protect-tool auf"
#: sm/gpgsm.c:251
msgid "change a passphrase"
msgstr "Das Mantra (Passphrase) ändern"
#: sm/gpgsm.c:261
msgid "create ascii armored output"
msgstr "Ausgabe mit ASCII Hülle wird erzeugt"
#: sm/gpgsm.c:263
msgid "create base-64 encoded output"
msgstr "Ausgabe im Basis-64 format erzeugen"
#: sm/gpgsm.c:265
msgid "assume input is in PEM format"
msgstr "Eingabedaten sind im PEM Format"
#: sm/gpgsm.c:267
msgid "assume input is in base-64 format"
msgstr "Eingabedaten sin im Basis-64 Format"
#: sm/gpgsm.c:269
msgid "assume input is in binary format"
msgstr "Eingabedaten sind im Binärformat"
#: sm/gpgsm.c:271
msgid "|NAME|encrypt for NAME"
msgstr "|NAME|Verschlüsseln für NAME"
#: sm/gpgsm.c:274
msgid "never consult a CRL"
msgstr "Niemals eine CRL konsultieren"
#: sm/gpgsm.c:279
msgid "check validity using OCSP"
msgstr "Die Gültigkeit mittels OCSP prüfen"
#: sm/gpgsm.c:282
msgid "|N|number of certificates to include"
msgstr "|N|Sende N Zertifikate mit"
#: sm/gpgsm.c:285
msgid "|FILE|take policy information from FILE"
msgstr "|DATEI|Richtlinieninformationen DATEI entnehmen"
#: sm/gpgsm.c:288
msgid "do not check certificate policies"
msgstr "Zertikikatrichtlinien nicht überprüfen"
#: sm/gpgsm.c:292
msgid "fetch missing issuer certificates"
msgstr "Fehlende Zertifikate automatisch holen"
#: sm/gpgsm.c:296
msgid "|NAME|use NAME as default recipient"
msgstr "|NAME|Benutze NAME als voreingestellten Empfänger"
#: sm/gpgsm.c:298
msgid "use the default key as default recipient"
msgstr "Benuzte voreingestellten Schlüssel als Standardempfänger"
#: sm/gpgsm.c:304
msgid "use this user-id to sign or decrypt"
msgstr "Benuzte diese Benutzer ID zum Signieren oder Entschlüsseln"
#: sm/gpgsm.c:307
msgid "|N|set compress level N (0 disables)"
msgstr "|N|Benutze Komprimierungsstufe N"
#: sm/gpgsm.c:309
msgid "use canonical text mode"
msgstr "Kanonischen Textmodus benutzen"
#: sm/gpgsm.c:312 tools/gpgconf.c:61
msgid "use as output file"
msgstr "als Ausgabedatei benutzen"
#: sm/gpgsm.c:315
msgid "don't use the terminal at all"
msgstr "Das Terminal überhaupt nicht benutzen"
#: sm/gpgsm.c:318
msgid "force v3 signatures"
msgstr "Version 3 Signaturen erzwingen"
#: sm/gpgsm.c:319
msgid "always use a MDC for encryption"
msgstr "Immer das MDC Verfahren zum verschlüsseln mitbenutzen"
#: sm/gpgsm.c:324
msgid "batch mode: never ask"
msgstr "Stapelverarbeitungs Modus: Nie nachfragen"
#: sm/gpgsm.c:325
msgid "assume yes on most questions"
msgstr "\"Ja\" auf die meisten Anfragen annehmen"
#: sm/gpgsm.c:326
msgid "assume no on most questions"
msgstr "\"Nein\" auf die meisten Anfragen annehmen"
#: sm/gpgsm.c:328
msgid "add this keyring to the list of keyrings"
msgstr "Diesen Keyring in die Liste der Keyrings aufnehmen"
#: sm/gpgsm.c:329
msgid "add this secret keyring to the list"
msgstr "Diese geheimen Keyring in die Liste aufnehmen"
#: sm/gpgsm.c:330
msgid "|NAME|use NAME as default secret key"
msgstr "|NAME|Benutze NAME als voreingestellten Schlüssel"
#: sm/gpgsm.c:331
msgid "|HOST|use this keyserver to lookup keys"
msgstr "|HOST|Benutze HOST als Schlüsselserver"
#: sm/gpgsm.c:332
msgid "|NAME|set terminal charset to NAME"
msgstr "|NAME|Den Zeichensatz für das Terminal auf NAME setzen"
#: sm/gpgsm.c:342
msgid "|FD|write status info to this FD"
msgstr "|FD|Statusinformationen auf Dateidescriptor FD schreiben"
#: sm/gpgsm.c:349
msgid "|FILE|load extension module FILE"
msgstr "|DATEI|Das Erweiterungsmodul DATEI laden"
#: sm/gpgsm.c:355
msgid "|NAME|use cipher algorithm NAME"
msgstr "|NAME|Den Verhsclüsselungsalgrithmus NAME benutzen"
#: sm/gpgsm.c:357
msgid "|NAME|use message digest algorithm NAME"
msgstr "|NAME|Den Hashalgorithmus NAME benutzen"
#: sm/gpgsm.c:359
msgid "|N|use compress algorithm N"
msgstr "|N|Den Kompressionsalgorithmus Nummer N benutzen"
#: sm/gpgsm.c:367
msgid ""
"@\n"
"(See the man page for a complete listing of all commands and options)\n"
msgstr ""
"@\n"
"(Die \"man\" Seite beschreibt alle Kommands und Optionen)\n"
#: sm/gpgsm.c:370
msgid ""
"@\n"
"Examples:\n"
"\n"
" -se -r Bob [file] sign and encrypt for user Bob\n"
" --clearsign [file] make a clear text signature\n"
" --detach-sign [file] make a detached signature\n"
" --list-keys [names] show keys\n"
" --fingerprint [names] show fingerprints\n"
msgstr ""
"@\n"
"Beispiele:\n"
"\n"
" -se -r Bob [Datei] Signieren und verschlüsseln für Benutzer Bob\\n\n"
" --clearsign [Datei] Eine Klartextsignatur erzeugen\\n\n"
" --detach-sign [Datei] Eine abgetrennte Signatur erzeugen\\n\n"
" --list-keys [Namen] Schlüssel anzeigenn\n"
" --fingerprint [Namen] \"Fingerabdrücke\" anzeigen\\n\n"
#: sm/gpgsm.c:484
msgid "Usage: gpgsm [options] [files] (-h for help)"
msgstr "Gebrauch: gpgsm [Optionen] [Dateien] (-h für Hilfe)"
#: sm/gpgsm.c:487
msgid ""
"Syntax: gpgsm [options] [files]\n"
"sign, check, encrypt or decrypt using the S/MIME protocol\n"
"default operation depends on the input data\n"
msgstr ""
"Gebrauch: gpgsm [Optionen] [Dateien]\n"
"Signieren, prüfen, ver- und entschlüsseln mittels S/MIME protocol\n"
#: sm/gpgsm.c:494
msgid ""
"\n"
"Supported algorithms:\n"
msgstr ""
"\n"
"Unterstützte Algorithmen:\n"
#: sm/gpgsm.c:575
msgid "usage: gpgsm [options] "
msgstr "Gebrauch: gpgsm [Optionen] "
#: sm/gpgsm.c:641
msgid "conflicting commands\n"
msgstr "Widersprechende Kommandos\n"
#: sm/gpgsm.c:657
#, c-format
msgid "can't encrypt to `%s': %s\n"
msgstr "Verschlüsseln für `%s' nicht möglich: %s\n"
#: sm/gpgsm.c:731
#, c-format
msgid "libksba is too old (need %s, have %s)\n"
msgstr "Die Bibliothek Libksba is nicht aktuell (benötige %s, habe %s)\n"
#: sm/gpgsm.c:1175
msgid "WARNING: program may create a core file!\n"
msgstr "WARNUNG: Programm könnte eine core-dump-Datei schreiben!\n"
#: sm/gpgsm.c:1187
msgid "WARNING: running with faked system time: "
msgstr "WARNUNG: Ausführung mit gefälschter Systemzeit: "
#: sm/gpgsm.c:1213
msgid "selected cipher algorithm is invalid\n"
msgstr "Das ausgewählte Verschlüsselungsverfahren ist ungültig\n"
#: sm/gpgsm.c:1221
msgid "selected digest algorithm is invalid\n"
msgstr "Das ausgewählte Hashverfahren ist ungültig\n"
#: sm/gpgsm.c:1251
#, c-format
msgid "can't sign using `%s': %s\n"
msgstr "Signieren mit `%s' nicht möglich: %s\n"
#: sm/gpgsm.c:1415
msgid "this command has not yet been implemented\n"
msgstr "Diee Kommando wurde noch nicht implementiert\n"
#: sm/gpgsm.c:1638 sm/gpgsm.c:1671
#, c-format
msgid "can't open `%s': %s\n"
msgstr "Datei `%s' kann nicht geöffnet werden: %s\n"
#: sm/import.c:118
#, c-format
msgid "total number processed: %lu\n"
msgstr "gesamte verarbeitete Anzahl: %lu\n"
#: sm/import.c:121
#, c-format
msgid " imported: %lu"
msgstr " importiert: %lu"
#: sm/import.c:125
#, c-format
msgid " unchanged: %lu\n"
msgstr " nicht geändert: %lu\n"
#: sm/import.c:127
#, c-format
msgid " secret keys read: %lu\n"
msgstr " gelesene private Schlüssel: %lu\n"
#: sm/import.c:129
#, c-format
msgid " secret keys imported: %lu\n"
msgstr "importierte priv. Schlüssel: %lu\n"
#: sm/import.c:131
#, c-format
msgid " secret keys unchanged: %lu\n"
msgstr "ungeänderte priv. Schlüssel: %lu\n"
#: sm/import.c:133
#, c-format
msgid " not imported: %lu\n"
msgstr " nicht importiert: %lu\n"
#: sm/import.c:229
msgid "error storing certificate\n"
msgstr "Fehler beim speichern des Zertifikats\n"
#: sm/import.c:237
msgid "basic certificate checks failed - not imported\n"
msgstr "Grundlegende Zertifikatprüfungen fehlgeschlagen - nicht importiert\n"
#: sm/import.c:423 sm/import.c:455
#, c-format
msgid "error importing certificate: %s\n"
msgstr "Fehler beim Importieren des Zertifikats: %s\n"
#: sm/import.c:484
#, c-format
msgid "error creating a pipe: %s\n"
msgstr "Fehler beim Erzeugen einer \"Pipe\": %s\n"
#: sm/import.c:492
#, c-format
msgid "error forking process: %s\n"
msgstr "Fehler beim \"Forken\" des Prozess: %s\n"
#: sm/import.c:590 sm/import.c:615
#, c-format
msgid "error creating temporary file: %s\n"
msgstr "Fehler beim Erstellen einer temporären Datei: %s\n"
#: sm/import.c:598
#, c-format
msgid "error writing to temporary file: %s\n"
msgstr "Fehler beim Schreiben auf eine temporäre Datei: %s\n"
#: sm/import.c:607
#, c-format
msgid "error reading input: %s\n"
msgstr "Fehler beim Lesen der Eingabe: %s\n"
#: sm/import.c:703
#, c-format
msgid "waiting for protect-tool to terminate failed: %s\n"
msgstr ""
"Das Warten auf die Beendigung des protect-tools ist fehlgeschlagen: %s\n"
#: sm/import.c:706
#, c-format
msgid "error running `%s': probably not installed\n"
msgstr "Feler bei Ausführung von `%s': wahrscheinlich nicht installiert\n"
#: sm/import.c:708
#, c-format
msgid "error running `%s': exit status %d\n"
msgstr "Fehler bei Ausführung von `%s': Endestatus %d\n"
#: sm/import.c:711
#, c-format
msgid "error running `%s': terminated\n"
msgstr "Fehler beim Ausführen von `%s': beendet\n"
#: sm/keydb.c:189
#, c-format
msgid "error creating keybox `%s': %s\n"
msgstr "Die \"Keybox\" `%s' konnte nicht erstellt werden: %s\n"
#: sm/keydb.c:192
msgid "you may want to start the gpg-agent first\n"
msgstr "Sie sollten zuerst den gpg-agent starten\n"
#: sm/keydb.c:197
#, c-format
msgid "keybox `%s' created\n"
msgstr "Die \"Keybox\" `%s' wurde erstellt\n"
#: sm/keydb.c:220
#, c-format
msgid "can't create lock for `%s'\n"
msgstr "Datei `%s' konnte nicht gesperrt werden\n"
#: sm/keydb.c:1327 sm/keydb.c:1389
msgid "failed to get the fingerprint\n"
msgstr "Kann den Fingerprint nicht ermitteln\n"
#: sm/keydb.c:1334 sm/keydb.c:1396
msgid "failed to allocate keyDB handle\n"
msgstr "Kann keinen KeyDB Handler bereitstellen\n"
#: sm/keydb.c:1351
#, c-format
msgid "problem looking for existing certificate: %s\n"
msgstr "Problem bei der Suche nach vorhandenem Zertifikat: %s\n"
#: sm/keydb.c:1359
#, c-format
msgid "error finding writable keyDB: %s\n"
msgstr "Fehler bei der Suche nach einer schreibbaren KeyDB: %s\n"
#: sm/keydb.c:1367
#, c-format
msgid "error storing certificate: %s\n"
msgstr "Fehler beim Speichern des Zertifikats: %s\n"
#: sm/keydb.c:1411
#, c-format
msgid "problem re-searching certificate: %s\n"
msgstr "Problem bei Wiederfinden des Zertifikats: %s\n"
#: sm/keydb.c:1420 sm/keydb.c:1508
#, c-format
msgid "error getting stored flags: %s\n"
msgstr "Fehler beim Holen der gespeicherten Flags: %s\n"
#: sm/keydb.c:1429 sm/keydb.c:1519
#, c-format
msgid "error storing flags: %s\n"
msgstr "Fehler beim Speichern der Flags: %s\n"
#: sm/verify.c:381
msgid "Signature made "
msgstr "Signatur erzeugt am "
#: sm/verify.c:385
msgid "[date not given]"
msgstr "[Datum nicht vorhanden]"
#: sm/verify.c:386
#, c-format
msgid " using certificate ID %08lX\n"
msgstr "mittels Zertifikat ID %08lX\n"
#: sm/verify.c:499
msgid "Good signature from"
msgstr "Korrekte Signatur von"
#: sm/verify.c:500
msgid " aka"
msgstr " alias"
#: tools/gpgconf.c:55
msgid "list all components"
msgstr "Liste aller Komponenten"
#: tools/gpgconf.c:56
msgid "|COMPONENT|list options"
msgstr "|KOMPONENTE|Zeige die Optionen an"
#: tools/gpgconf.c:57
msgid "|COMPONENT|change options"
msgstr "|KOMPONENTE|Ändere die Optionen"
#: tools/gpgconf.c:63
msgid "quiet"
msgstr "Weniger Ausgaben"
#: tools/gpgconf.c:65
msgid "activate changes at runtime, if possible"
msgstr "Aktiviere Änderungen zur Laufzeit; falls möglich"
#: tools/gpgconf.c:88
msgid "Usage: gpgconf [options] (-h for help)"
msgstr "Gebrauch: gpgconf [Optionen] (-h für Hilfe)"
#: tools/gpgconf.c:91
msgid ""
"Syntax: gpgconf [options]\n"
"Manage configuration options for tools of the GnuPG system\n"
msgstr ""
"Syntax: gpgconf {Optionen]\n"
"Verwalte Konfigurationsoptionen für Programme des GnuPG Systems\n"
#: tools/gpgconf.c:180
msgid "usage: gpgconf [options] "
msgstr "Gebrauch: gpgconf [Optionen] "
#: tools/gpgconf.c:181
msgid "Need one component argument"
msgstr "Benötige ein Komponenten Argument"
#: tools/gpgconf.c:190
msgid "Component not found"
msgstr "Komponente nicht gefunden"
#~ msgid "Enter passphrase:"
#~ msgstr "Bitte das Mantra (Passphrase) eingeben:"
#~ msgid "[error]"
#~ msgstr "[Fehler]"
#~ msgid "no key usage specified - accepted for encryption\n"
#~ msgstr ""
#~ "Schlüsselverwendungszweck nicht vorhanden - wird zum Verschlüsseln "
#~ "akzeptiert\n"
diff --git a/scd/sc-investigate.c b/scd/sc-investigate.c
index 8d34ab77e..1f1920650 100644
--- a/scd/sc-investigate.c
+++ b/scd/sc-investigate.c
@@ -1,812 +1,812 @@
/* sc-investigate.c - A tool to look around on smartcards.
* Copyright (C) 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#include <config.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <ctype.h>
#include <unistd.h>
#ifdef USE_GNU_PTH
# include <pth.h>
#endif
#ifdef HAVE_READLINE_READLINE_H
#include <readline/readline.h>
#include <readline/history.h>
#endif
#define JNLIB_NEED_LOG_LOGV
#include "scdaemon.h"
#include <gcrypt.h>
#include "apdu.h" /* for open_reader */
#include "atr.h"
#include "app-common.h"
#include "iso7816.h"
#define _(a) (a)
#define CONTROL_D ('D' - 'A' + 1)
enum cmd_and_opt_values
{
oInteractive = 'i',
oVerbose = 'v',
oQuiet = 'q',
oReaderPort = 500,
octapiDriver,
oDebug,
oDebugAll,
oDisableCCID,
oGenRandom,
aTest };
static ARGPARSE_OPTS opts[] = {
{ 301, NULL, 0, "@Options:\n " },
{ oInteractive, "interactive", 0, "start in interactive explorer mode"},
{ oQuiet, "quiet", 0, "quiet" },
{ oVerbose, "verbose", 0, "verbose" },
{ oReaderPort, "reader-port", 2, "|N|connect to reader at port N"},
- { octapiDriver, "ctapi-driver", 2, "NAME|use NAME as ctAPI driver"},
+ { octapiDriver, "ctapi-driver", 2, "|NAME|use NAME as ctAPI driver"},
{ oDisableCCID, "disable-ccid", 0,
#ifdef HAVE_LIBUSB
"do not use the internal CCID driver"
#else
"@"
#endif
},
{ oDebug, "debug" ,4|16, "set debugging flags"},
{ oDebugAll, "debug-all" ,0, "enable full debugging"},
{ oGenRandom, "gen-random", 4, "|N|generate N bytes of random"},
{0}
};
#ifndef HAVE_OPENSC
#ifdef USE_GNU_PTH
/* Pth wrapper function definitions. */
GCRY_THREAD_OPTION_PTH_IMPL;
#endif /*USE_GNU_PTH*/
#endif /*!HAVE_OPENSC*/
static void interactive_shell (int slot);
static void dump_other_cards (int slot);
static const char *
my_strusage (int level)
{
const char *p;
switch (level)
{
case 11: p = "sc-investigate (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: sc-investigate [options] (-h for help)\n");
break;
case 41: p = _("Syntax: sc-investigate [options] [args]]\n"
"Have a look at smartcards\n");
break;
default: p = NULL;
}
return p;
}
/* Used by gcry for logging */
static void
my_gcry_logger (void *dummy, int level, const char *fmt, va_list arg_ptr)
{
/* translate the log levels */
switch (level)
{
case GCRY_LOG_CONT: level = JNLIB_LOG_CONT; break;
case GCRY_LOG_INFO: level = JNLIB_LOG_INFO; break;
case GCRY_LOG_WARN: level = JNLIB_LOG_WARN; break;
case GCRY_LOG_ERROR:level = JNLIB_LOG_ERROR; break;
case GCRY_LOG_FATAL:level = JNLIB_LOG_FATAL; break;
case GCRY_LOG_BUG: level = JNLIB_LOG_BUG; break;
case GCRY_LOG_DEBUG:level = JNLIB_LOG_DEBUG; break;
default: level = JNLIB_LOG_ERROR; break;
}
log_logv (level, fmt, arg_ptr);
}
int
main (int argc, char **argv )
{
ARGPARSE_ARGS pargs;
int slot, rc;
const char *reader_port = NULL;
unsigned long gen_random = 0;
int interactive = 0;
set_strusage (my_strusage);
gcry_control (GCRYCTL_SUSPEND_SECMEM_WARN);
log_set_prefix ("sc-investigate", 1);
/* Try to auto set the character set. */
set_native_charset (NULL);
/* Libgcrypt requires us to register the threading model first. We
can't use pth at all if we are using OpenSC becuase OpenSC uses
ptreads. Note that this will also do the pth_init. */
#ifndef HAVE_OPENSC
#ifdef USE_GNU_PTH
rc = gcry_control (GCRYCTL_SET_THREAD_CBS, &gcry_threads_pth);
if (rc)
{
log_fatal ("can't register GNU Pth with Libgcrypt: %s\n",
gpg_strerror (rc));
}
#endif /*USE_GNU_PTH*/
#endif /*!HAVE_OPENSC*/
/* Check that the libraries are suitable. Do it here because
the option parsing may need services of the library */
if (!gcry_check_version (NEED_LIBGCRYPT_VERSION) )
{
log_fatal( _("libgcrypt is too old (need %s, have %s)\n"),
NEED_LIBGCRYPT_VERSION, gcry_check_version (NULL) );
}
gcry_set_log_handler (my_gcry_logger, NULL);
/* FIXME? gcry_control (GCRYCTL_USE_SECURE_RNDPOOL);*/
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 oQuiet: opt.quiet++; break;
case oDebug: opt.debug |= pargs.r.ret_ulong; break;
case oDebugAll: opt.debug = ~0; break;
case oReaderPort: reader_port = pargs.r.ret_str; break;
case octapiDriver: opt.ctapi_driver = pargs.r.ret_str; break;
case oDisableCCID: opt.disable_ccid = 1; break;
case oGenRandom: gen_random = pargs.r.ret_ulong; break;
case oInteractive: interactive = 1; break;
default : pargs.err = 2; break;
}
}
if (log_get_errorcount(0))
exit(2);
if (opt.verbose < 2)
opt.verbose = 2; /* Hack to let select_openpgp print some info. */
if (argc)
usage (1);
slot = apdu_open_reader (reader_port);
if (slot == -1)
exit (1);
if (!gen_random && !opt.quiet)
{
rc = atr_dump (slot, stdout);
if (rc)
log_error ("can't dump ATR: %s\n", gpg_strerror (rc));
}
if (interactive)
interactive_shell (slot);
else
{
struct app_ctx_s appbuf;
/* Fixme: We better use app.c directly. */
memset (&appbuf, 0, sizeof appbuf);
appbuf.slot = slot;
rc = app_select_openpgp (&appbuf);
if (rc)
{
if (!opt.quiet)
log_info ("selecting openpgp failed: %s\n", gpg_strerror (rc));
memset (&appbuf, 0, sizeof appbuf);
appbuf.slot = slot;
rc = app_select_dinsig (&appbuf);
if (rc)
{
if (!opt.quiet)
log_info ("selecting dinsig failed: %s\n", gpg_strerror (rc));
dump_other_cards (slot);
}
else
{
appbuf.initialized = 1;
log_info ("dinsig application selected\n");
}
}
else
{
appbuf.initialized = 1;
log_info ("openpgp application selected\n");
if (gen_random)
{
size_t nbytes;
unsigned char *buffer;
buffer = xmalloc (4096);
do
{
nbytes = gen_random > 4096? 4096 : gen_random;
rc = app_get_challenge (&appbuf, nbytes, buffer);
if (rc)
log_error ("app_get_challenge failed: %s\n",gpg_strerror (rc));
else
{
if (fwrite (buffer, nbytes, 1, stdout) != 1)
log_error ("writing to stdout failed: %s\n",
strerror (errno));
gen_random -= nbytes;
}
}
while (gen_random && !log_get_errorcount (0));
xfree (buffer);
}
}
}
return log_get_errorcount (0)? 2:0;
}
void
send_status_info (CTRL ctrl, const char *keyword, ...)
{
/* DUMMY */
}
/* Dump BUFFER of length NBYTES in a nicely human readable format. */
static void
dump_buffer (const unsigned char *buffer, size_t nbytes)
{
int i;
while (nbytes)
{
for (i=0; i < 16 && i < nbytes; i++)
printf ("%02X%s ", buffer[i], i==8? " ":"");
for (; i < 16; i++)
printf (" %s ", i==8? " ":"");
putchar (' ');
putchar (' ');
for (i=0; i < 16 && i < nbytes; i++)
if (isprint (buffer[i]))
putchar (buffer[i]);
else
putchar ('.');
nbytes -= i;
buffer += i;
for (; i < 16; i++)
putchar (' ');
putchar ('\n');
}
}
static void
dump_or_store_buffer (const char *arg,
const unsigned char *buffer, size_t nbytes)
{
const char *s = strchr (arg, '>');
int append;
FILE *fp;
if (!s)
{
dump_buffer (buffer, nbytes);
return;
}
if ((append = (*++s == '>')))
s++;
fp = fopen (s, append? "ab":"wb");
if (!fp)
{
log_error ("failed to create `%s': %s\n", s, strerror (errno));
return;
}
if (nbytes && fwrite (buffer, nbytes, 1, fp) != 1)
log_error ("failed to write to `%s': %s\n", s, strerror (errno));
if (fclose (fp))
log_error ("failed to close `%s': %s\n", s, strerror (errno));
}
/* Convert STRING into a a newly allocated buffer and return the
length of the buffer in R_LENGTH. Detect xx:xx:xx... sequence and
unhexify that one. */
static unsigned char *
pin_to_buffer (const char *string, size_t *r_length)
{
unsigned char *buffer = xmalloc (strlen (string)+1);
const char *s;
size_t n;
for (s=string, n=0; *s; s += 3)
{
if (hexdigitp (s) && hexdigitp (s+1) && (s[2]==':'||!s[2]))
{
buffer[n++] = xtoi_2 (s);
if (!s[2])
break;
}
else
{
memcpy (buffer, string, strlen (string));
*r_length = strlen (string);
return buffer;
}
}
*r_length = n;
return buffer;
}
static char *
my_read_line (int use_readline, char *prompt)
{
static char buf[256];
#ifdef HAVE_READLINE
if (use_readline)
{
char *line = readline (prompt);
if (line)
trim_spaces (line);
if (line && strlen (line) > 2 )
add_history (line);
return line;
}
#endif
/* Either we don't have readline or we are not running
interactively */
#ifndef HAVE_READLINE
printf ("%s", prompt );
#endif
fflush(stdout);
if (!fgets(buf, sizeof(buf), stdin))
return NULL;
if (!strlen(buf))
return NULL;
if (buf[strlen (buf)-1] == '\n')
buf[strlen (buf)-1] = 0;
trim_spaces (buf);
return buf;
}
/* Run a shell for interactive exploration of the card. */
static void
interactive_shell (int slot)
{
enum cmdids
{
cmdNOP = 0,
cmdQUIT, cmdHELP,
cmdSELECT,
cmdCHDIR,
cmdLS,
cmdAPP,
cmdREAD,
cmdREADREC,
cmdREADSHORTREC,
cmdDEBUG,
cmdVERIFY,
cmdCHANGEREF,
cmdREADPK,
cmdINVCMD
};
static struct
{
const char *name;
enum cmdids id;
const char *desc;
} cmds[] = {
{ "quit" , cmdQUIT , "quit this menu" },
{ "q" , cmdQUIT , NULL },
{ "help" , cmdHELP , "show this help" },
{ "?" , cmdHELP , NULL },
{ "debug" , cmdDEBUG, "set debugging flags" },
{ "select" , cmdSELECT, "select file (EF)" },
{ "s" , cmdSELECT, NULL },
{ "chdir" , cmdCHDIR, "change directory (select DF)"},
{ "cd" , cmdCHDIR, NULL },
{ "ls" , cmdLS, "list directory (some cards only)"},
{ "app" , cmdAPP, "select application"},
{ "read" , cmdREAD, "read binary" },
{ "rb" , cmdREAD, NULL },
{ "readrec", cmdREADREC, "read record(s)" },
{ "rr" , cmdREADREC, NULL },
{ "rsr" , cmdREADSHORTREC, "readshortrec RECNO SHORT_EF" },
{ "verify" , cmdVERIFY, "verify CHVNO PIN" },
{ "ver" , cmdVERIFY, NULL },
{ "changeref", cmdCHANGEREF, "change reference data" },
{ "readpk", cmdREADPK, "read a public key" },
{ NULL, cmdINVCMD }
};
enum cmdids cmd = cmdNOP;
int use_readline = isatty (fileno(stdin));
char *line;
gpg_error_t err = 0;
unsigned char *result = NULL;
size_t resultlen;
#ifdef HAVE_READLINE
if (use_readline)
using_history ();
#endif
for (;;)
{
int arg_number;
const char *arg_string = "";
const char *arg_next = "";
char *p;
int i;
if (err)
printf ("command failed: %s\n", gpg_strerror (err));
err = 0;
xfree (result);
result = NULL;
printf ("\n");
do
{
line = my_read_line (use_readline, "cmd> ");
}
while ( line && *line == '#' );
arg_number = 0;
if (!line || *line == CONTROL_D)
cmd = cmdQUIT;
else if (!*line)
cmd = cmdNOP;
else {
if ((p=strchr (line,' ')))
{
char *endp;
*p++ = 0;
trim_spaces (line);
trim_spaces (p);
arg_number = strtol (p, &endp, 0);
arg_string = p;
if (endp != p)
{
arg_next = endp;
while ( spacep (arg_next) )
arg_next++;
}
}
for (i=0; cmds[i].name; i++ )
if (!ascii_strcasecmp (line, cmds[i].name ))
break;
cmd = cmds[i].id;
}
switch (cmd)
{
case cmdHELP:
for (i=0; cmds[i].name; i++ )
if (cmds[i].desc)
printf("%-10s %s\n", cmds[i].name, _(cmds[i].desc) );
break;
case cmdQUIT:
goto leave;
case cmdNOP:
break;
case cmdDEBUG:
if (!*arg_string)
opt.debug = opt.debug? 0 : 2048;
else
opt.debug = arg_number;
break;
case cmdSELECT:
err = iso7816_select_file (slot, arg_number, 0, NULL, NULL);
break;
case cmdCHDIR:
err = iso7816_select_file (slot, arg_number, 1, NULL, NULL);
break;
case cmdLS:
err = iso7816_list_directory (slot, 1, &result, &resultlen);
if (!err || gpg_err_code (err) == GPG_ERR_ENOENT)
err = iso7816_list_directory (slot, 0, &result, &resultlen);
/* FIXME: Do something with RESULT. */
break;
case cmdAPP:
{
app_t app;
app = select_application (NULL, slot, *arg_string? arg_string:NULL);
if (app)
{
char *sn;
app_get_serial_and_stamp (app, &sn, NULL);
log_info ("application `%s' ready; sn=%s\n",
app->apptype?app->apptype:"?", sn? sn:"[none]");
release_application (app);
}
}
break;
case cmdREAD:
err = iso7816_read_binary (slot, 0, 0, &result, &resultlen);
if (!err)
dump_or_store_buffer (arg_string, result, resultlen);
break;
case cmdREADREC:
if (*arg_string == '*' && (!arg_string[1] || arg_string[1] == ' '))
{
/* Fixme: Can't write to a file yet. */
for (i=1, err=0; !err; i++)
{
xfree (result); result = NULL;
err = iso7816_read_record (slot, i, 1, 0,
&result, &resultlen);
if (!err)
dump_buffer (result, resultlen);
}
if (gpg_err_code (err) == GPG_ERR_NOT_FOUND)
err = 0;
}
else
{
err = iso7816_read_record (slot, arg_number, 1, 0,
&result, &resultlen);
if (!err)
dump_or_store_buffer (arg_string, result, resultlen);
}
break;
case cmdREADSHORTREC:
{
int short_ef;
short_ef = strtol (arg_next, NULL, 0);
if (short_ef < 1 || short_ef > 254)
printf ("error: short EF must be between 1 and 254\n");
else
{
err = iso7816_read_record (slot, arg_number, 1, short_ef,
&result, &resultlen);
if (!err)
dump_or_store_buffer (arg_string, result, resultlen);
}
}
break;
case cmdVERIFY:
if (arg_number < 0 || arg_number > 255 || (arg_number & 127) > 31)
printf ("error: invalid CHVNO\n");
else
{
unsigned char *pin;
size_t pinlen;
pin = pin_to_buffer (arg_next, &pinlen);
err = iso7816_verify (slot, arg_number, pin, pinlen);
xfree (pin);
}
break;
case cmdCHANGEREF:
{
const char *newpin = arg_next;
while ( *newpin && !spacep (newpin) )
newpin++;
while ( spacep (newpin) )
newpin++;
if (arg_number < 0 || arg_number > 255 || (arg_number & 127) > 31)
printf ("error: invalid CHVNO\n");
else if (!*arg_next || !*newpin || newpin == arg_next)
printf ("usage: changeref CHVNO OLDPIN NEWPIN\n");
else
{
char *oldpin = xstrdup (arg_next);
unsigned char *oldpin_buf, *newpin_buf;
size_t oldpin_len, newpin_len;
for (p=oldpin; *p && !spacep (p); p++ )
;
*p = 0;
oldpin_buf = pin_to_buffer (oldpin, &oldpin_len);
newpin_buf = pin_to_buffer (newpin, &newpin_len);
err = iso7816_change_reference_data (slot, arg_number,
oldpin_buf, oldpin_len,
newpin_buf, newpin_len);
xfree (newpin_buf);
xfree (oldpin_buf);
xfree (oldpin);
}
}
break;
case cmdREADPK:
if (arg_number < 1 || arg_number > 255)
printf ("usage: readpk CRTBYTE1\n");
else
{
unsigned char crt[2];
crt[0] = arg_number;
crt[1] = 0;
err = iso7816_read_public_key(slot, crt, 2,
&result, &resultlen);
if (!err)
dump_or_store_buffer (arg_string, result, resultlen);
}
break;
case cmdINVCMD:
default:
printf ("\n");
printf ("Invalid command (try \"help\")\n");
break;
} /* End command switch. */
} /* End of main menu loop. */
leave:
;
}
/* Figure out whether the current card is a German Geldkarte and print
what we know about it. */
static int
dump_geldkarte (int slot)
{
unsigned char *r = NULL;
size_t rlen;
const char *t;
if (iso7816_read_record (slot, 1, 1, 0xbc, &r, &rlen))
return -1;
/* We require that the record is at least 24 bytes, the first byte
is 0x67 and the filler byte is correct. */
if (rlen < 24 || *r != 0x67 || r[22])
return -1;
/* The short Bankleitzahl consists of 3 bytes at offset 1. */
switch (r[1])
{
case 0x21: t = "Oeffentlich-rechtliche oder private Bank"; break;
case 0x22: t = "Privat- oder Geschäftsbank"; break;
case 0x25: t = "Sparkasse"; break;
case 0x26:
case 0x29: t = "Genossenschaftsbank"; break;
default:
xfree (r);
return -1; /* Probably not a Geldkarte. */
}
printf ("KBLZ .....: %02X-%02X%02X (%s)\n", r[1], r[2], r[3], t);
printf ("Card-No ..: %02X%02X%02X%02X%02X\n", r[4], r[5], r[6], r[7], r[8]);
/* Byte 10 enthält im linken Halbbyte eine Prüfziffer, die nach dem */
/* Verfahren 'Luhn formula for computing modulus 10' über die Ziffern der */
/* ersten 9 Byte berechnet ist. */
/* Das rechte Halbbyte wird zu 'D' gesetzt. */
/* Für die Berechnung der Luhn-Prüfziffer sind die folgenden Schritte */
/* durchzuführen: */
/* Schritt 1: Mit der rechtesten Ziffer beginnend ist einschließlich dieser */
/* Ziffer jede übernächste Ziffer zu verdoppeln (mit 2 multiplizieren). */
/* Schritt 2: Die einzelnen Ziffern der Produkte aus Schritt 1 und die bei */
/* diesen Multiplikationen unberührt gebliebenen Ziffern sind zu addieren. */
/* Schritt 3: Das Ergebnis der Addition aus Schritt 2 ist von dem auf die */
/* nächst höhere Zahl mit der Einerstelle 0 aufgerundeten Ergebnis der */
/* Addition aus Schritt 2 abzuziehen. Wenn das Ergebnis der Addition aus */
/* Schritt 2 bereits eine Zahl mit der Einerstelle 0 ergibt (z.B. 30, 40, */
/* usw.), ist die Prüfziffer 0. */
/* Beispiel: Kartennummer ohne Prüfziffer: 992 839 871 */
/* 9 9 2 8 3 9 8 7 1 */
/* x 2 x 2 x 2 x 2 x 2 Schritt 1 */
/* 18 4 6 16 2 */
/* 1+8 +9 +4 +8 +6 +9 +1+6 +7 +2 = 61 Schritt 2 */
/* 70-61 = 9 Schritt 3 */
/* Prüfziffer zu 992 839 871 = 9 */
printf ("Expires at: %02X/%02X\n", r[11], r[10] );
printf ("Valid from: %02X.%02X.%02X\n", r[14], r[13], r[12]);
printf ("Country ..: %02X%02X\n", r[15], r[16]);
printf ("Currency .: %c%c%c\n", isascii (r[17])? r[17]:' ',
isascii (r[18])? r[18]:' ', isascii (r[19])? r[19]:' ');
printf ("Cur.-Mult : %s\n",
r[20] == 0x01? "0.01":
r[20] == 0x02? "0.1":
r[20] == 0x04? "1":
r[20] == 0x08? "10":
r[20] == 0x10? "100":
r[20] == 0x20? "1000": "?");
printf ("ZKA ChipID: %02X\n", r[21]);
printf ("OS version: %02X\n", r[23]);
xfree (r);
return 0;
}
/* Try to figure out the type of teh card and dump its contents. */
static void
dump_other_cards (int slot)
{
if (!dump_geldkarte (slot))
return;
}
diff --git a/sm/ChangeLog b/sm/ChangeLog
index 51f46c335..951c8db17 100644
--- a/sm/ChangeLog
+++ b/sm/ChangeLog
@@ -1,1246 +1,1261 @@
+2004-08-17 Werner Koch <wk@g10code.de>
+
+ * import.c (check_and_store): Do a full validation if
+ --with-validation is set.
+
+ * certchain.c (gpgsm_basic_cert_check): Print more detailed error
+ messages.
+
+ * certcheck.c (do_encode_md): Partly support DSA. Add new arg
+ PKALGO. Changed all callers to pass it.
+ (pk_algo_from_sexp): New.
+
2004-08-16 Werner Koch <wk@g10code.de>
+ * gpgsm.c: New option --fixed-passphrase.
+ * import.c (popen_protect_tool): Pass it to the protect-tool.
+
* server.c (cmd_encrypt): Use DEFAULT_RECPLIST and not recplist
for encrypt-to keys.
2004-08-06 Werner Koch <wk@g10code.com>
* gpgsm.c: New option --with-ephemeral-keys.
* keylist.c (list_internal_keys): Set it here.
(list_cert_raw): And indicate those keys. Changed all our callers
to pass the new arg HD through.
2004-07-23 Werner Koch <wk@g10code.de>
* certreqgen.c (proc_parameters): Do not allow key length below
1024.
2004-07-22 Werner Koch <wk@g10code.de>
* keylist.c (list_cert_raw): Print the keygrip.
2004-07-20 Werner Koch <wk@gnupg.org>
* certchain.c (gpgsm_validate_chain): The trust check didn't
worked anymore, probably due to the changes at 2003-03-04. Fixed.
2004-06-06 Werner Koch <wk@gnupg.org>
* certreqgen.c (get_parameter_uint, create_request): Create
an extension for key usage when requested.
2004-05-12 Werner Koch <wk@gnupg.org>
* gpgsm.c (main): Install emergency_cleanup also as an atexit
handler.
* verify.c (gpgsm_verify): Removed the separate error code
handling for KSBA. We use shared error codes anyway.
* export.c (export_p12): Removed debugging code.
* encrypt.c (gpgsm_encrypt): Put the session key in to secure memory.
2004-05-11 Werner Koch <wk@gnupg.org>
* sign.c (gpgsm_sign): Include the error source in the final error
message.
* decrypt.c (gpgsm_decrypt): Ditto.
* fingerprint.c (gpgsm_get_key_algo_info): New.
* sign.c (gpgsm_sign): Don't assume RSA in the status line.
* keylist.c (list_cert_colon): Really print the algorithm and key
length.
(list_cert_raw, list_cert_std): Ditto.
(list_cert_colon): Reorganized to be able to tell whether a root
certificate is trusted.
* gpgsm.c: New option --debug-allow-core-dump.
* gpgsm.h (opt): Add member CONFIG_FILENAME.
* gpgsm.c (main): Use it here instead of the local var.
* server.c (gpgsm_server): Print some additional information with
the hello in verbose mode.
2004-04-30 Werner Koch <wk@gnupg.org>
* import.c (check_and_store): Do not update the stats for hidden
imports of issuer certs.
(popen_protect_tool): Request statusmessages from the protect-tool.
(parse_p12): Detect status messages. Add new arg STATS and update them.
(print_imported_summary): Include secret key stats.
2004-04-28 Werner Koch <wk@gnupg.org>
* gpgsm.c: New command --keydb-clear-some-cert-flags.
* keydb.c (keydb_clear_some_cert_flags): New.
(keydb_update_keyblock, keydb_set_flags): Change error code
CONFLICT to NOT_LOCKED.
2004-04-26 Werner Koch <wk@gnupg.org>
* gpgsm.c (main) <gpgconf>: Do not use /dev/null as default config
filename.
* call-agent.c (gpgsm_agent_pksign, gpgsm_agent_pkdecrypt)
(gpgsm_agent_genkey, gpgsm_agent_istrusted)
(gpgsm_agent_marktrusted, gpgsm_agent_havekey)
(gpgsm_agent_passwd): Add new arg CTRL and changed all callers.
(start_agent): New arg CTRL. Send progress item when starting a
new agent.
* sign.c (gpgsm_get_default_cert, get_default_signer): New arg
CTRL to be passed down to the agent function.
* decrypt.c (prepare_decryption): Ditto.
* certreqgen.c (proc_parameters, read_parameters): Ditto.
* certcheck.c (gpgsm_create_cms_signature): Ditto.
2004-04-23 Werner Koch <wk@gnupg.org>
* keydb.c (keydb_add_resource): Try to compress the file on init.
* keylist.c (oidtranstbl): New. OIDs collected from several sources.
(print_name_raw, print_names_raw, list_cert_raw): New.
(gpgsm_list_keys): Check the dump mode and pass it down as
necessary.
2004-04-22 Werner Koch <wk@gnupg.org>
* gpgsm.c (main): New commands --dump-keys, --dump-external-keys,
--dump-secret-keys.
2004-04-13 Werner Koch <wk@gnupg.org>
* misc.c (setup_pinentry_env): New.
* import.c (popen_protect_tool): Call it.
* export.c (popen_protect_tool): Call it.
2004-04-08 Werner Koch <wk@gnupg.org>
* decrypt.c (gpgsm_decrypt): Return GPG_ERR_NO_DATA if it is not a
encrypted message.
2004-04-07 Werner Koch <wk@gnupg.org>
* gpgsm.c: New option --force-crl-refresh.
* call-dirmngr.c (gpgsm_dirmngr_isvalid): Pass option to dirmngr.
2004-04-05 Werner Koch <wk@gnupg.org>
* server.c (get_status_string): Add STATUS_NEWSIG.
* verify.c (gpgsm_verify): Print STATUS_NEWSIG for each signature.
* certchain.c (gpgsm_validate_chain) <gpgsm_cert_use_cer_p>: Do
not just warn if a cert is not suitable; bail out immediately.
2004-04-01 Werner Koch <wk@gnupg.org>
* call-dirmngr.c (isvalid_status_cb): New.
(unhexify_fpr): New. Taken from ../g10/call-agent.c
(gpgsm_dirmngr_isvalid): Add new arg CTRL, changed caller to pass
it thru. Detect need to check the respondert cert and do that.
* certchain.c (gpgsm_validate_chain): Add new arg FLAGS. Changed
all callers.
2004-03-24 Werner Koch <wk@gnupg.org>
* sign.c (gpgsm_sign): Include a short list of capabilities.
2004-03-17 Werner Koch <wk@gnupg.org>
* gpgsm.c (main) <gpgconf>: Fixed default value quoting.
2004-03-16 Werner Koch <wk@gnupg.org>
* gpgsm.c (main): Implemented --gpgconf-list.
2004-03-15 Werner Koch <wk@gnupg.org>
* keylist.c (list_cert_colon): Hack to set the expired flag.
2004-03-09 Werner Koch <wk@gnupg.org>
* gpgsm.c (main): Correctly intitialze USE_OCSP flag.
* keydb.c (keydb_delete): s/GPG_ERR_CONFLICT/GPG_ERR_NOT_LOCKED/
2004-03-04 Werner Koch <wk@gnupg.org>
* call-dirmngr.c (gpgsm_dirmngr_isvalid): New arg ISSUER_CERT.
* certchain.c (is_cert_still_valid): New. Code moved from ...
(gpgsm_validate_chain): ... here because we now need to check at
two places and at a later stage, so that we can pass the issuer
cert down to the dirmngr.
2004-03-03 Werner Koch <wk@gnupg.org>
* call-agent.c (start_agent): Replaced pinentry setup code by a
call to a new common function.
* certdump.c (gpgsm_format_keydesc): Make sure the string is
returned as utf-8.
* export.c (gpgsm_export): Make sure that we don't export more
than one certificate.
2004-03-02 Werner Koch <wk@gnupg.org>
* export.c (create_duptable, destroy_duptable)
(insert_duptable): New.
(gpgsm_export): Avoid duplicates.
2004-02-26 Werner Koch <wk@gnupg.org>
* certchain.c (compare_certs): New.
(gpgsm_validate_chain): Fixed infinite certificate checks after
bad signatures.
2004-02-24 Werner Koch <wk@gnupg.org>
* keylist.c (list_cert_colon): Print the fingerprint as the
cert-id for root certificates.
2004-02-21 Werner Koch <wk@gnupg.org>
* keylist.c (list_internal_keys): Return error codes.
(list_external_keys, gpgsm_list_keys): Ditto.
* server.c (do_listkeys): Ditto.
* gpgsm.c (main): Display a key description for --passwd.
* call-agent.c (gpgsm_agent_passwd): New arg DESC.
2004-02-20 Werner Koch <wk@gnupg.org>
* gpgsm.c (main): New option --debug-ignore-expiration.
* certchain.c (gpgsm_validate_chain): Use it here.
* certlist.c (cert_usage_p): Apply extKeyUsage.
2004-02-19 Werner Koch <wk@gnupg.org>
* export.c (export_p12, popen_protect_tool)
(gpgsm_p12_export): New.
* gpgsm.c (main): New command --export-secret-key-p12.
2004-02-18 Werner Koch <wk@gnupg.org>
* gpgsm.c (set_debug): Set the new --debug-level flags.
(main): New option --gpgconf-list.
(main): Do not setup -u and -r keys when not required.
(main): Setup the used character set.
* keydb.c (keydb_add_resource): Print a hint to start the
gpg-agent.
2004-02-17 Werner Koch <wk@gnupg.org>
* gpgsm.c: Fixed value parsing for --with-validation.
* call-agent.c (start_agent): Ignore an empty GPG_AGENT_INFO.
* call-dirmngr.c (start_dirmngr): Likewise for DIRMNGR_INFO.
* gpgsm.c: New option --with-md5-fingerprint.
* keylist.c (list_cert_std): Print MD5 fpr.
* gpgsm.c: New options --with-validation.
* server.c (option_handler): New option "with-validation".
* keylist.c (list_cert_std, list_internal_keys): New args CTRL and
WITH_VALIDATION. Changed callers to set it.
(list_external_cb, list_external_keys): Pass CTRL to the callback.
(list_cert_colon): Add arg CTRL. Check validation if requested.
* certchain.c (unknown_criticals, allowed_ca, check_cert_policy)
(gpgsm_validate_chain): New args LISTMODE and FP.
(do_list): New helper for info output.
(find_up): New arg FIND_NEXT.
(gpgsm_validate_chain): After a bad signature try again with other
CA certificates.
* import.c (print_imported_status): New arg NEW_CERT. Print
additional STATUS_IMPORT_OK becuase that is what gpgme expects.
(check_and_store): Always call above function after import.
* server.c (get_status_string): Added STATUS_IMPORT_OK.
2004-02-13 Werner Koch <wk@gnupg.org>
* certcheck.c (gpgsm_create_cms_signature): Format a description
for use by the pinentry.
* decrypt.c (gpgsm_decrypt): Ditto. Free HEXKEYGRIP.
* certdump.c (format_name_cookie, format_name_writer)
(gpgsm_format_name): New.
(gpgsm_format_serial): New.
(gpgsm_format_keydesc): New.
* call-agent.c (gpgsm_agent_pksign): New arg DESC.
(gpgsm_agent_pkdecrypt): Ditto.
* encrypt.c (init_dek): Check for too weak algorithms.
* import.c (parse_p12, popen_protect_tool): New.
* base64.c (gpgsm_create_reader): New arg ALLOW_MULTI_PEM.
Changed all callers.
(base64_reader_cb): Handle it here.
(gpgsm_reader_eof_seen): New.
(base64_reader_cb): Set a flag for EOF.
(simple_reader_cb): Ditto.
2004-02-12 Werner Koch <wk@gnupg.org>
* gpgsm.h, gpgsm.c: New option --protect-tool-program.
* gpgsm.c (run_protect_tool): Use it.
2004-02-11 Werner Koch <wk@gnupg.org>
* Makefile.am (AM_CPPFLAGS): Pass directory constants via -D; this
will allow to override directory names at make time.
2004-02-02 Werner Koch <wk@gnupg.org>
* import.c (check_and_store): Import certificates even with
missing issuer's cert. Fixed an "depending on the verbose
setting" bug.
* certchain.c (gpgsm_validate_chain): Mark revoked certs in the
keybox.
* keylist.c (list_cert_colon): New arg VALIDITY; use it to print a
revoked flag.
(list_internal_keys): Retrieve validity flag.
(list_external_cb): Pass 0 as validity flag.
* keydb.c (keydb_get_flags, keydb_set_flags): New.
(keydb_set_cert_flags): New.
(lock_all): Return a proper error code.
(keydb_lock): New.
(keydb_delete): Don't lock but check that it has been locked.
(keydb_update_keyblock): Ditto.
* delete.c (delete_one): Take a lock.
2004-01-30 Werner Koch <wk@gnupg.org>
* certchain.c (check_cert_policy): Fixed read error checking.
(check_cert_policy): With no critical policies issue only a
warning if the policy file does not exists.
* sign.c (add_certificate_list): Decrement N for the first cert.
2004-01-29 Werner Koch <wk@gnupg.org>
* certdump.c (parse_dn_part): Map common OIDs to human readable
labels. Make sure that a value won't get truncated if it includes
a Nul.
2004-01-28 Werner Koch <wk@gnupg.org>
* certchain.c (gpgsm_validate_chain): Changed the message printed
for an untrusted root certificate.
2004-01-27 Werner Koch <wk@gnupg.org>
* certdump.c (parse_dn_part): Pretty print the nameDistinguisher OID.
(print_dn_part): Do not delimit multiple RDN by " + ". Handle
multi-valued RDNs in a special way, i.e. in the order specified by
the certificate.
(print_dn_parts): Simplified.
2004-01-16 Werner Koch <wk@gnupg.org>
* sign.c (gpgsm_sign): Print an error message on all failures.
* decrypt.c (gpgsm_decrypt): Ditto.
2003-12-17 Werner Koch <wk@gnupg.org>
* server.c (gpgsm_server): Add arg DEFAULT_RECPLIST.
(cmd_encrypt): Add all enrypt-to marked certs to the list.
* encrypt.c (gpgsm_encrypt): Check that real recipients are
available.
* gpgsm.c (main): Make the --encrypt-to and --no-encrypt-to
options work. Pass the list of recients to gpgsm_server.
* gpgsm.h (certlist_s): Add field IS_ENCRYPT_TO.
(opt): Add NO_ENCRYPT_TO.
* certlist.c (gpgsm_add_to_certlist): New arg IS_ENCRYPT_TO.
Changed all callers and ignore duplicate entries.
(is_cert_in_certlist): New.
(gpgsm_add_cert_to_certlist): New.
* certdump.c (gpgsm_print_serial): Cleaned up cast use in strtoul.
(gpgsm_dump_serial): Ditto.
* decrypt.c (gpgsm_decrypt): Replaced ERR by RC.
2003-12-16 Werner Koch <wk@gnupg.org>
* gpgsm.c (main): Set the prefixes for assuan logging.
* sign.c (gpgsm_sign): Add validation checks for the default
certificate.
* gpgsm.c: Add -k as alias for --list-keys and -K for
--list-secret-keys.
2003-12-15 Werner Koch <wk@gnupg.org>
* encrypt.c (init_dek): Use gry_create_nonce for the IV; there is
not need for real strong random here and it even better protect
the random bits used for the key.
2003-12-01 Werner Koch <wk@gnupg.org>
* gpgsm.c, gpgsm.h: New options --{enable,disable}-ocsp.
(gpgsm_init_default_ctrl): Set USE_OCSP to the default value.
* certchain.c (gpgsm_validate_chain): Handle USE_OCSP.
* call-dirmngr.c (gpgsm_dirmngr_isvalid): Add arg USE_OCSP and
proceed accordingly.
2003-11-19 Werner Koch <wk@gnupg.org>
* verify.c (gpgsm_verify): Use "0" instead of an empty string for
the VALIDSIG status.
2003-11-18 Werner Koch <wk@gnupg.org>
* verify.c (gpgsm_verify): Fixed for changes API of gcry_md_info.
* certchain.c (unknown_criticals): Fixed an error code test.
2003-11-12 Werner Koch <wk@gnupg.org>
Adjusted for API changes in Libksba.
2003-10-31 Werner Koch <wk@gnupg.org>
* certchain.c (gpgsm_validate_chain): Changed to use ksba_isotime_t.
* verify.c (strtimestamp_r, gpgsm_verify): Ditto.
* sign.c (gpgsm_sign): Ditto.
* keylist.c (print_time, list_cert_std, list_cert_colon): Ditto.
* certdump.c (gpgsm_print_time, gpgsm_dump_time, gpgsm_dump_cert):
Ditto.
2003-10-25 Werner Koch <wk@gnupg.org>
* certreqgen.c (read_parameters): Fixed faulty of !spacep().
2003-08-20 Marcus Brinkmann <marcus@g10code.de>
* encrypt.c (encode_session_key): Allocate enough space. Cast key
byte to unsigned char to prevent sign extension.
(encrypt_dek): Check return value before error.
2003-08-14 Timo Schulz <twoaday@freakmail.de>
* encrypt.c (encode_session_key): Use new Libgcrypt interface.
2003-07-31 Werner Koch <wk@gnupg.org>
* Makefile.am (gpgsm_LDADD): Added INTLLIBS.
2003-07-29 Werner Koch <wk@gnupg.org>
* gpgsm.c (main): Add secmem features and set the random seed file.
(gpgsm_exit): Update the random seed file and enable debug output.
2003-07-27 Werner Koch <wk@gnupg.org>
Adjusted for gcry_mpi_print and gcry_mpi_scan API change.
2003-06-24 Werner Koch <wk@gnupg.org>
* server.c (gpgsm_status_with_err_code): New.
* verify.c (gpgsm_verify): Use it here instead of the old
tokenizing version.
* verify.c (strtimestamp): Renamed to strtimestamp_r
Adjusted for changes in the libgcrypt API. Some more fixes for the
libgpg-error stuff.
2003-06-04 Werner Koch <wk@gnupg.org>
* call-agent.c (init_membuf,put_membuf,get_membuf): Removed.
Include new membuf header and changed used type.
Renamed error codes from INVALID to INV and removed _ERROR suffixes.
2003-06-03 Werner Koch <wk@gnupg.org>
Changed all error codes in all files to the new libgpg-error scheme.
* gpgsm.h: Include gpg-error.h .
* Makefile.am: Link with libgpg-error.
2003-04-29 Werner Koch <wk@gnupg.org>
* Makefile.am: Use libassuan. Don't override LDFLAGS anymore.
* server.c (register_commands): Adjust for new Assuan semantics.
2002-12-03 Werner Koch <wk@gnupg.org>
* call-agent.c (gpgsm_agent_passwd): New.
* gpgsm.c (main): New command --passwd and --call-protect-tool
(run_protect_tool): New.
2002-11-25 Werner Koch <wk@gnupg.org>
* verify.c (gpgsm_verify): Handle content-type attribute.
2002-11-13 Werner Koch <wk@gnupg.org>
* call-agent.c (start_agent): Try to use $GPG_TTY instead of
ttyname. Changed ttyname to test stdin becuase it can be assumed
that output redirection is more common that input redirection.
2002-11-12 Werner Koch <wk@gnupg.org>
* gpgsm.c: New command --call-dirmngr.
* call-dirmngr.c (gpgsm_dirmngr_run_command)
(run_command_inq_cb,run_command_cb)
(run_command_status_cb): New.
2002-11-11 Werner Koch <wk@gnupg.org>
* certcheck.c (gpgsm_check_cms_signature): Don't double free
s_sig but free s_pkey at leave.
2002-11-10 Werner Koch <wk@gnupg.org>
* gpgsm.c: Removed duplicate --list-secret-key entry.
2002-09-19 Werner Koch <wk@gnupg.org>
* certcheck.c (gpgsm_check_cert_sig): Add cert hash debugging.
* certchain.c (find_up): Print info when the cert was not found
by the autorithyKeyIdentifier.
2002-09-03 Werner Koch <wk@gnupg.org>
* gpgsm.c (main): Disable the internal libgcrypt locking.
2002-08-21 Werner Koch <wk@gnupg.org>
* import.c (print_imported_summary): Cleaned up. Print new
not_imported value.
(check_and_store): Update non_imported counter.
(print_import_problem): New.
(check_and_store): Print error status message.
* server.c (get_status_string): Added STATUS_IMPORT_PROBLEM.
2002-08-20 Werner Koch <wk@gnupg.org>
* gpgsm.c (main): Use the log file only in server mode.
* import.c (print_imported_summary): New.
(check_and_store): Update the counters, take new argument.
(import_one): Factored out core of gpgsm_import.
(gpgsm_import): Print counters.
(gpgsm_import_files): New.
* gpgsm.c (main): Use the new function for import.
2002-08-19 Werner Koch <wk@gnupg.org>
* decrypt.c (gpgsm_decrypt): Return a better error status token.
* verify.c (gpgsm_verify): Don't error on messages with no signing
time or no message digest. This is only the case for messages
without any signed attributes.
2002-08-16 Werner Koch <wk@gnupg.org>
* certpath.c: Renamed to ..
* certchain.c: this. Renamed all all other usages of "path" in the
context of certificates to "chain".
* call-agent.c (learn_cb): Special treatment when the issuer
certificate is missing.
2002-08-10 Werner Koch <wk@gnupg.org>
* Makefile.am (INCLUDES): Add definition for localedir.
* keylist.c (list_cert_colon): Print the short fingerprint in the
key ID field.
* fingerprint.c (gpgsm_get_short_fingerprint): New.
* verify.c (gpgsm_verify): Print more verbose info for a good
signature.
2002-08-09 Werner Koch <wk@gnupg.org>
* decrypt.c (prepare_decryption): Hack to detected already
unpkcsedone keys.
* gpgsm.c (emergency_cleanup): New.
(main): Initialize the signal handler.
* sign.c (gpgsm_sign): Reset the hash context for subsequent
signers and release it at the end.
2002-08-05 Werner Koch <wk@gnupg.org>
* server.c (cmd_signer): New command "SIGNER"
(register_commands): Register it.
(cmd_sign): Pass the signer list to gpgsm_sign.
* certlist.c (gpgsm_add_to_certlist): Add SECRET argument, check
for secret key if set and changed all callers.
* sign.c (gpgsm_sign): New argument SIGNERLIST and implemt
multiple signers.
* gpgsm.c (main): Support more than one -u.
* server.c (cmd_recipient): Return reason code 1 for No_Public_Key
which is actually what gets returned from add_to_certlist.
2002-07-26 Werner Koch <wk@gnupg.org>
* certcheck.c (gpgsm_check_cert_sig): Implement proper cleanup.
(gpgsm_check_cms_signature): Ditto.
2002-07-22 Werner Koch <wk@gnupg.org>
* keydb.c (keydb_add_resource): Register a lock file.
(lock_all, unlock_all): Implemented.
* delete.c: New.
* gpgsm.c: Made --delete-key work.
* server.c (cmd_delkeys): New.
(register_commands): New command DELKEYS.
* decrypt.c (gpgsm_decrypt): Print a convenience note when RC2 is
used and a STATUS_ERROR with the algorithm oid.
2002-07-03 Werner Koch <wk@gnupg.org>
* server.c (gpgsm_status2): Insert a blank between all optional
arguments when using assuan.
* server.c (cmd_recipient): No more need for extra blank in constants.
* import.c (print_imported_status): Ditto.
* gpgsm.c (main): Ditto.
2002-07-02 Werner Koch <wk@gnupg.org>
* verify.c (gpgsm_verify): Extend the STATUS_BADSIG line with
the fingerprint.
* certpath.c (check_cert_policy): Don't use log_error to print a
warning.
* keydb.c (keydb_store_cert): Add optional ar EXISTED and changed
all callers.
* call-agent.c (learn_cb): Print info message only for real imports.
* import.c (gpgsm_import): Moved duplicated code to ...
(check_and_store): new function. Added magic to import the entire
chain. Print status only for real imports and moved printing code
to ..
(print_imported_status): New.
* call-dirmngr.c (gpgsm_dirmngr_isvalid): print status of dirmngr
call in very verbose mode.
* gpgsm.c (main): Use the same error codes for STATUS_INV_RECP as
with the server mode.
2002-06-29 Werner Koch <wk@gnupg.org>
* gpgsm.c: New option --auto-issuer-key-retrieve.
* certpath.c (find_up): Try to retrieve an issuer key from an
external source and from the ephemeral key DB.
(find_up_store_certs_cb): New.
* keydb.c (keydb_set_ephemeral): Does now return the old
state. Call the backend only when required.
* call-dirmngr.c (start_dirmngr): Use GNUPG_DEFAULT_DIRMNGR.
(lookup_status_cb): Issue status only when CTRL is not NULL.
(gpgsm_dirmngr_lookup): Document that CTRL is optional.
* call-agent.c (start_agent): Use GNUPG_DEFAULT_AGENT.
2002-06-28 Werner Koch <wk@gnupg.org>
* server.c (cmd_recipient): Add more reason codes.
2002-06-27 Werner Koch <wk@gnupg.org>
* certpath.c (gpgsm_basic_cert_check): Use
--debug-no-path-validation to also bypass this basic check.
* gpgsm.c (main): Use GNUPG_DEFAULT_HOMEDIR constant.
* call-agent.c (start_agent): Create and pass the list of FD to
keep in the child to assuan.
* call-dirmngr.c (start_dirmngr): Ditto.
2002-06-26 Werner Koch <wk@gnupg.org>
* import.c (gpgsm_import): Print an STATUS_IMPORTED.
* gpgsm.c: --debug-no-path-validation does not take an argument.
2002-06-25 Werner Koch <wk@gnupg.org>
* certdump.c (print_dn_part): Always print a leading slash,
removed NEED_DELIM arg and changed caller.
* export.c (gpgsm_export): Print LFs to FP and not stdout.
(print_short_info): Ditto. Make use of gpgsm_print_name.
* server.c (cmd_export): Use output-fd instead of data lines; this
was actually the specified way.
2002-06-24 Werner Koch <wk@gnupg.org>
* gpgsm.c: Removed duped help entry for --list-keys.
* gpgsm.c, gpgsm.h: New option --debug-no-path-validation.
* certpath.c (gpgsm_validate_path): Use it here instead of the
debug flag hack.
* certpath.c (check_cert_policy): Return No_Policy_Match if the
policy file could not be opened.
2002-06-20 Werner Koch <wk@gnupg.org>
* certlist.c (gpgsm_add_to_certlist): Fixed locating of a
certificate with the required key usage.
* gpgsm.c (main): Fixed a segv when using --outfile without an
argument.
* keylist.c (print_capabilities): Also check for non-repudiation
and data encipherment.
* certlist.c (cert_usage_p): Test for signing and encryption was
swapped. Add a case for certification usage, handle
non-repudiation and data encipherment.
(gpgsm_cert_use_cert_p): New.
(gpgsm_add_to_certlist): Added a CTRL argument and changed all
callers to pass it.
* certpath.c (gpgsm_validate_path): Use it here to print a status
message. Added a CTRL argument and changed all callers to pass it.
* decrypt.c (gpgsm_decrypt): Print a status message for wrong key
usage.
* verify.c (gpgsm_verify): Ditto.
* keydb.c (classify_user_id): Allow a colon delimited fingerprint.
2002-06-19 Werner Koch <wk@gnupg.org>
* call-agent.c (learn_cb): Use log_info instead of log_error on
successful import.
* keydb.c (keydb_set_ephemeral): New.
(keydb_store_cert): New are ephemeral, changed all callers.
* keylist.c (list_external_cb): Store cert as ephemeral.
* export.c (gpgsm_export): Kludge to export epehmeral certificates.
* gpgsm.c (main): New command --list-external-keys.
2002-06-17 Werner Koch <wk@gnupg.org>
* certreqgen.c (read_parameters): Improved error handling.
(gpgsm_genkey): Print error message.
2002-06-13 Werner Koch <wk@gnupg.org>
* gpgsm.c (main): New option --log-file.
2002-06-12 Werner Koch <wk@gnupg.org>
* call-dirmngr.c (lookup_status_cb): New.
(gpgsm_dirmngr_lookup): Use the status CB. Add new arg CTRL and
changed caller to pass it.
* gpgsm.c (open_fwrite): New.
(main): Allow --output for --verify.
* sign.c (hash_and_copy_data): New.
(gpgsm_sign): Implemented normal (non-detached) signatures.
* gpgsm.c (main): Ditto.
* certpath.c (gpgsm_validate_path): Special error handling for
no policy match.
2002-06-10 Werner Koch <wk@gnupg.org>
* server.c (get_status_string): Add STATUS_ERROR.
* certpath.c (gpgsm_validate_path): Tweaked the error checking to
return error codes in a more sensitive way.
* verify.c (gpgsm_verify): Send status TRUST_NEVER also for a bad
CA certificate and when the certificate has been revoked. Issue
TRUST_FULLY even when the cert has expired. Append an error token
to these status lines. Issue the new generic error status when a
cert was not found and when leaving the function.
2002-06-04 Werner Koch <wk@gnupg.org>
* gpgsm.c (main): New command --list-sigs
* keylist.c (list_cert_std): New. Use it whenever colon mode is
not used.
(list_cert_chain): New.
2002-05-31 Werner Koch <wk@gnupg.org>
* gpgsm.c (main): Don't print the "go ahead" message for an
invalid command.
2002-05-23 Werner Koch <wk@gnupg.org>
* import.c (gpgsm_import): Add error messages.
2002-05-21 Werner Koch <wk@gnupg.org>
* keylist.c (list_internal_keys): Renamed from gpgsm_list_keys.
(list_external_keys): New.
(gpgsm_list_keys): Dispatcher for above.
* call-dirmngr.c (lookup_cb,pattern_from_strlist)
(gpgsm_dirmngr_lookup): New.
* server.c (option_handler): Handle new option --list-mode.
(do_listkeys): Handle options and actually use the mode argument.
(get_status_string): New code TRUNCATED.
* import.c (gpgsm_import): Try to identify the type of input and
handle certs-only messages.
2002-05-14 Werner Koch <wk@gnupg.org>
* gpgsm.c: New option --faked-system-time
* sign.c (gpgsm_sign): And use it here.
* certpath.c (gpgsm_validate_path): Ditto.
2002-05-03 Werner Koch <wk@gnupg.org>
* certpath.c (gpgsm_validate_path): Added EXPTIME arg and changed
all callers.
* verify.c (gpgsm_verify): Tweaked usage of log_debug and
log_error. Return EXPSIG status and add expiretime to VALIDSIG.
2002-04-26 Werner Koch <wk@gnupg.org>
* gpgsm.h (DBG_AGENT,DBG_AGENT_VALUE): Replaced by DBG_ASSUAN_*.
Changed all users.
* call-agent.c (start_agent): Be more silent without -v.
* call-dirmngr.c (start_dirmngr): Ditto.
2002-04-25 Werner Koch <wk@gnupg.org>
* call-agent.c (start_agent): Make copies of old locales and check
for setlocale.
2002-04-25 Marcus Brinkmann <marcus@g10code.de>
* call-agent.c (start_agent): Fix error handling logic so the
locale is always correctly reset.
2002-04-25 Marcus Brinkmann <marcus@g10code.de>
* server.c (option_handler): Accept display, ttyname, ttytype,
lc_ctype and lc_messages options.
* gpgsm.c (main): Allocate memory for these options.
* gpgsm.h (struct opt): Make corresponding members non-const.
2002-04-24 Marcus Brinkmann <marcus@g10code.de>
* gpgsm.h (struct opt): New members display, ttyname, ttytype,
lc_ctype, lc_messages.
* gpgsm.c (enum cmd_and_opt_values): New members oDisplay,
oTTYname, oTTYtype, oLCctype, oLCmessages.
(opts): New entries for these options.
(main): Handle these new options.
* call-agent.c (start_agent): Set the various display and tty
parameter after resetting.
2002-04-18 Werner Koch <wk@gnupg.org>
* certreqgen.c (gpgsm_genkey): Write status output on success.
2002-04-15 Werner Koch <wk@gnupg.org>
* gpgsm.c (main): Check ksba version.
* certpath.c (find_up): New to use the authorithKeyIdentifier.
Use it in all other functions to locate the signing cert..
2002-04-11 Werner Koch <wk@gnupg.org>
* certlist.c (cert_usable_p): New.
(gpgsm_cert_use_sign_p,gpgsm_cert_use_encrypt_p): New.
(gpgsm_cert_use_verify_p,gpgsm_cert_use_decrypt_p): New.
(gpgsm_add_to_certlist): Check the key usage.
* sign.c (gpgsm_sign): Ditto.
* verify.c (gpgsm_verify): Print a message wehn an unsuitable
certificate was used.
* decrypt.c (gpgsm_decrypt): Ditto
* keylist.c (print_capabilities): Determine values from the cert.
2002-03-28 Werner Koch <wk@gnupg.org>
* keylist.c (list_cert_colon): Fixed listing of crt record; the
issuer is not at the right place. Print a chainingID.
* certpath.c (gpgsm_walk_cert_chain): Be a bit more silent on
common errors.
2002-03-21 Werner Koch <wk@gnupg.org>
* export.c: New.
* gpgsm.c: Add command --export.
* server.c (cmd_export): New.
2002-03-13 Werner Koch <wk@gnupg.org>
* decrypt.c (gpgsm_decrypt): Allow multiple recipients.
2002-03-12 Werner Koch <wk@gnupg.org>
* certpath.c (check_cert_policy): Print the policy list.
* verify.c (gpgsm_verify): Detect certs-only message.
2002-03-11 Werner Koch <wk@gnupg.org>
* import.c (gpgsm_import): Print a notice about imported certificates
when in verbose mode.
* gpgsm.c (main): Print INV_RECP status.
* server.c (cmd_recipient): Ditto.
* server.c (gpgsm_status2): New. Allows for a list of strings.
(gpgsm_status): Divert to gpgsm_status2.
* encrypt.c (gpgsm_encrypt): Don't use a default key when no
recipients are given. Print a NO_RECP status.
2002-03-06 Werner Koch <wk@gnupg.org>
* server.c (cmd_listkeys, cmd_listsecretkeys): Divert to
(do_listkeys): new. Add pattern parsing.
* keylist.c (gpgsm_list_keys): Handle selection pattern.
* gpgsm.c: New command --learn-card
* call-agent.c (learn_cb,gpgsm_agent_learn): New.
* gpgsm.c (main): Print error messages for non-implemented commands.
* base64.c (base64_reader_cb): Use case insensitive compare of the
Content-Type string to detect plain base-64.
2002-03-05 Werner Koch <wk@gnupg.org>
* gpgsm.c, gpgsm.h: Add local_user.
* sign.c (gpgsm_get_default_cert): New.
(get_default_signer): Use the new function if local_user is not
set otherwise used that value.
* encrypt.c (get_default_recipient): Removed.
(gpgsm_encrypt): Use gpgsm_get_default_cert.
* verify.c (gpgsm_verify): Better error text for a bad signature
found by comparing the hashs.
2002-02-27 Werner Koch <wk@gnupg.org>
* call-dirmngr.c, call-agent.c: Add 2 more arguments to all uses
of assuan_transact.
2002-02-25 Werner Koch <wk@gnupg.org>
* server.c (option_handler): Allow to use -2 for "send all certs
except the root cert".
* sign.c (add_certificate_list): Implement it here.
* certpath.c (gpgsm_is_root_cert): New.
2002-02-19 Werner Koch <wk@gnupg.org>
* certpath.c (check_cert_policy): New.
(gpgsm_validate_path): And call it from here.
* gpgsm.c (main): New options --policy-file,
--disable-policy-checks and --enable-policy-checks.
* gpgsm.h (opt): Added policy_file, no_policy_checks.
2002-02-18 Werner Koch <wk@gnupg.org>
* certpath.c (gpgsm_validate_path): Ask the agent to add the
certificate into the trusted list.
* call-agent.c (gpgsm_agent_marktrusted): New.
2002-02-07 Werner Koch <wk@gnupg.org>
* certlist.c (gpgsm_add_to_certlist): Check that the specified
name identifies a certificate unambiguously.
(gpgsm_find_cert): Ditto.
* server.c (cmd_listkeys): Check that the data stream is available.
(cmd_listsecretkeys): Ditto.
(has_option): New.
(cmd_sign): Fix ambiguousity in option recognition.
* gpgsm.c (main): Enable --logger-fd.
* encrypt.c (gpgsm_encrypt): Increased buffer size for better
performance.
* call-agent.c (gpgsm_agent_pksign): Check the S-Exp received from
the agent.
* keylist.c (list_cert_colon): Filter out control characters.
2002-02-06 Werner Koch <wk@gnupg.org>
* decrypt.c (gpgsm_decrypt): Bail out after an decryption error.
* server.c (reset_notify): Close input and output FDs.
(cmd_encrypt,cmd_decrypt,cmd_verify,cmd_sign.cmd_import)
(cmd_genkey): Close the FDs and release the recipient list even in
the error case.
2002-02-01 Marcus Brinkmann <marcus@g10code.de>
* sign.c (gpgsm_sign): Do not release certificate twice.
2002-01-29 Werner Koch <wk@gnupg.org>
* call-agent.c (gpgsm_agent_havekey): New.
* keylist.c (list_cert_colon): New arg HAVE_SECRET, print "crs"
when we know that the secret key is available.
(gpgsm_list_keys): New arg MODE, check whether a secret key is
available. Changed all callers.
* gpgsm.c (main): New command --list-secret-keys.
* server.c (cmd_listsecretkeys): New.
(cmd_listkeys): Return secret keys with "crs" record.
2002-01-28 Werner Koch <wk@gnupg.org>
* certreqgen.c (create_request): Store the email address in the req.
2002-01-25 Werner Koch <wk@gnupg.org>
* gpgsm.c (main): Disable core dumps.
* sign.c (add_certificate_list): New.
(gpgsm_sign): Add the certificates to the CMS object.
* certpath.c (gpgsm_walk_cert_chain): New.
* gpgsm.h (server_control_s): Add included_certs.
* gpgsm.c: Add option --include-certs.
(gpgsm_init_default_ctrl): New.
(main): Call it.
* server.c (gpgsm_server): Ditto.
(option_handler): Support --include-certs.
2002-01-23 Werner Koch <wk@gnupg.org>
* certpath.c (gpgsm_validate_path): Print the DN of a missing issuer.
* certdump.c (gpgsm_dump_string): New.
(print_dn): Replaced by above.
2002-01-22 Werner Koch <wk@gnupg.org>
* certpath.c (unknown_criticals): New.
(allowed_ca): New.
(gpgsm_validate_path): Check validity, CA attribute, path length
and unknown critical extensions.
2002-01-21 Werner Koch <wk@gnupg.org>
* gpgsm.c: Add option --enable-crl-checks.
* call-agent.c (start_agent): Implemented socket based access.
* call-dirmngr.c (start_dirmngr): Ditto.
2002-01-20 Werner Koch <wk@gnupg.org>
* server.c (option_handler): New.
(gpgsm_server): Register it with assuan.
2002-01-19 Werner Koch <wk@gnupg.org>
* server.c (gpgsm_server): Use assuan_deinit_server and setup
assuan logging if enabled.
* call-agent.c (inq_ciphertext_cb): Don't show the session key in
an Assuan log file.
* gpgsm.c (my_strusage): Take bugreport address from configure.ac
2002-01-15 Werner Koch <wk@gnupg.org>
* import.c (gpgsm_import): Just do a basic cert check before
storing it.
* certpath.c (gpgsm_basic_cert_check): New.
* keydb.c (keydb_store_cert): New.
* import.c (store_cert): Removed and change all caller to use
the new function.
* verify.c (store_cert): Ditto.
* certlist.c (gpgsm_add_to_certlist): Validate the path
* certpath.c (gpgsm_validate_path): Check the trust list.
* call-agent.c (gpgsm_agent_istrusted): New.
2002-01-14 Werner Koch <wk@gnupg.org>
* call-dirmngr.c (inq_certificate): Changed for new interface semantic.
* certlist.c (gpgsm_find_cert): New.
2002-01-13 Werner Koch <wk@gnupg.org>
* fingerprint.c (gpgsm_get_certid): Print the serial and not the
hash after the dot.
2002-01-11 Werner Koch <wk@gnupg.org>
* call-dirmngr.c: New.
* certpath.c (gpgsm_validate_path): Check the CRL here.
* fingerprint.c (gpgsm_get_certid): New.
* gpgsm.c: New options --dirmngr-program and --disable-crl-checks.
2002-01-10 Werner Koch <wk@gnupg.org>
* base64.c (gpgsm_create_writer): Allow to set the object name
2002-01-08 Werner Koch <wk@gnupg.org>
* keydb.c (spacep): Removed because it is now in util.c
* server.c (cmd_genkey): New.
* certreqgen.c: New. The parameter handling code has been taken
from gnupg/g10/keygen.c version 1.0.6.
* call-agent.c (gpgsm_agent_genkey): New.
2002-01-02 Werner Koch <wk@gnupg.org>
* server.c (rc_to_assuan_status): Removed and changed all callers
to use map_to_assuan_status.
2001-12-20 Werner Koch <wk@gnupg.org>
* verify.c (gpgsm_verify): Implemented non-detached signature
verification. Add OUT_FP arg, initialize a writer and changed all
callers.
* server.c (cmd_verify): Pass an out_fp if one has been set.
* base64.c (base64_reader_cb): Try to detect an S/MIME body part.
* certdump.c (print_sexp): Renamed to gpgsm_dump_serial, made
global.
(print_time): Renamed to gpgsm_dump_time, made global.
(gpgsm_dump_serial): Take a real S-Expression as argument and
print the first item.
* keylist.c (list_cert_colon): Ditto.
* keydb.c (keydb_search_issuer_sn): Ditto.
* decrypt.c (print_integer_sexp): Removed and made callers
use gpgsm_dump_serial.
* verify.c (print_time): Removed, made callers use gpgsm_dump_time.
2001-12-19 Marcus Brinkmann <marcus@g10code.de>
* call-agent.c (start_agent): Add new argument to assuan_pipe_connect.
2001-12-18 Werner Koch <wk@gnupg.org>
* verify.c (print_integer_sexp): Renamed from print_integer and
print the serial number according to the S-Exp rules.
* decrypt.c (print_integer_sexp): Ditto.
2001-12-17 Werner Koch <wk@gnupg.org>
* keylist.c (list_cert_colon): Changed for new return value of
get_serial.
* keydb.c (keydb_search_issuer_sn): Ditto.
* certcheck.c (gpgsm_check_cert_sig): Likewise for other S-Exp
returingin functions.
* fingerprint.c (gpgsm_get_keygrip): Ditto.
* encrypt.c (encrypt_dek): Ditto
* certcheck.c (gpgsm_check_cms_signature): Ditto
* decrypt.c (prepare_decryption): Ditto.
* call-agent.c (gpgsm_agent_pkdecrypt): Removed arg ciphertextlen,
use KsbaSexp type and calculate the length.
* certdump.c (print_sexp): Remaned from print_integer, changed caller.
* Makefile.am: Use the LIBGCRYPT and LIBKSBA variables.
* fingerprint.c (gpgsm_get_keygrip): Use the new
gcry_pk_get_keygrip to calculate the grip - note the algorithm and
therefore the grip values changed.
2001-12-15 Werner Koch <wk@gnupg.org>
* certcheck.c (gpgsm_check_cms_signature): Removed the faked-key
kludge.
(gpgsm_create_cms_signature): Removed the commented fake key
code. This makes the function pretty simple.
* gpgsm.c (main): Renamed the default key database to "keyring.kbx".
* decrypt.c (gpgsm_decrypt): Write STATUS_DECRYPTION_*.
* sign.c (gpgsm_sign): Write a STATUS_SIG_CREATED.
2001-12-14 Werner Koch <wk@gnupg.org>
* keylist.c (list_cert_colon): Kludge to show an email address
encoded in the subject's DN.
* verify.c (gpgsm_verify): Add hash debug helpers
* sign.c (gpgsm_sign): Ditto.
* base64.c (base64_reader_cb): Reset the linelen when we need to
skip the line and adjusted test; I somehow forgot about DeMorgan.
* server.c (cmd_encrypt,cmd_decrypt,cmd_sign,cmd_verify)
(cmd_import): Close the FDs on success.
(close_message_fd): New.
(input_notify): Setting autodetect_encoding to 0 after initializing
it to 0 is pretty pointless. Easy to fix.
* gpgsm.c (main): New option --debug-wait n, so that it is
possible to attach gdb when used in server mode.
* sign.c (get_default_signer): Use keydb_classify_name here.
2001-12-14 Marcus Brinkmann <marcus@g10code.de>
* call-agent.c (LINELENGTH): Removed.
(gpgsm_agent_pksign): Use ASSUAN_LINELENGTH, not LINELENGTH.
(gpgsm_agent_pkdecrypt): Likewise.
2001-12-13 Werner Koch <wk@gnupg.org>
* keylist.c (list_cert_colon): Print alternative names of subject
and a few other values.
2001-12-12 Werner Koch <wk@gnupg.org>
* gpgsm.c (main): New options --assume-{armor,base64,binary}.
* base64.c (base64_reader_cb): Fixed non-autodetection mode.
2001-12-04 Werner Koch <wk@gnupg.org>
* call-agent.c (read_from_agent): Check for inquire responses.
(request_reply): Handle them using a new callback arg, changed all
callers.
(gpgsm_agent_pkdecrypt): New.
2001-11-27 Werner Koch <wk@gnupg.org>
* base64.c: New. Changed all other functions to use this instead
of direct creation of ksba_reader/writer.
* gpgsm.c (main): Set ctrl.auto_encoding unless --no-armor is used.
2001-11-26 Werner Koch <wk@gnupg.org>
* gpgsm.c: New option --agent-program
* call-agent.c (start_agent): Allow to override the default path
to the agent.
* keydb.c (keydb_add_resource): Create keybox
* keylist.c (gpgsm_list_keys): Fixed non-server keylisting.
* server.c (rc_to_assuan_status): New. Use it for all commands.
Copyright 2001, 2002, 2003 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.
diff --git a/sm/certchain.c b/sm/certchain.c
index 8d54767f8..2ce247f65 100644
--- a/sm/certchain.c
+++ b/sm/certchain.c
@@ -1,979 +1,983 @@
/* certchain.c - certificate chain validation
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#include <config.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <time.h>
#include <stdarg.h>
#include <assert.h>
#define JNLIB_NEED_LOG_LOGV /* We need log_logv. */
#include "gpgsm.h"
#include <gcrypt.h>
#include <ksba.h>
#include "keydb.h"
#include "../kbx/keybox.h" /* for KEYBOX_FLAG_* */
#include "i18n.h"
-/* If LISTMODE is true, print FORMAT in liting mode to FP. If
+/* If LISTMODE is true, print FORMAT using LISTMODE to FP. If
LISTMODE is false, use the string to print an log_info or, if
- IS_ERROR is true, an log_error. */
+ IS_ERROR is true, and log_error. */
static void
do_list (int is_error, int listmode, FILE *fp, const char *format, ...)
{
va_list arg_ptr;
va_start (arg_ptr, format) ;
if (listmode)
{
if (fp)
{
fputs (" [", fp);
vfprintf (fp, format, arg_ptr);
fputs ("]\n", fp);
}
}
else
{
log_logv (is_error? JNLIB_LOG_ERROR: JNLIB_LOG_INFO, format, arg_ptr);
log_printf ("\n");
}
va_end (arg_ptr);
}
/* Return 0 if A and B are equal. */
static int
compare_certs (ksba_cert_t a, ksba_cert_t b)
{
const unsigned char *img_a, *img_b;
size_t len_a, len_b;
img_a = ksba_cert_get_image (a, &len_a);
if (!img_a)
return 1;
img_b = ksba_cert_get_image (b, &len_b);
if (!img_b)
return 1;
return !(len_a == len_b && !memcmp (img_a, img_b, len_a));
}
static int
unknown_criticals (ksba_cert_t cert, int listmode, FILE *fp)
{
static const char *known[] = {
"2.5.29.15", /* keyUsage */
"2.5.29.19", /* basic Constraints */
"2.5.29.32", /* certificatePolicies */
"2.5.29.37", /* extendedKeyUsage - handled by certlist.c */
NULL
};
int rc = 0, i, idx, crit;
const char *oid;
gpg_error_t err;
for (idx=0; !(err=ksba_cert_get_extension (cert, idx,
&oid, &crit, NULL, NULL));idx++)
{
if (!crit)
continue;
for (i=0; known[i] && strcmp (known[i],oid); i++)
;
if (!known[i])
{
do_list (1, listmode, fp,
_("critical certificate extension %s is not supported"),
oid);
rc = gpg_error (GPG_ERR_UNSUPPORTED_CERT);
}
}
if (err && gpg_err_code (err) != GPG_ERR_EOF)
rc = err;
return rc;
}
static int
allowed_ca (ksba_cert_t cert, int *chainlen, int listmode, FILE *fp)
{
gpg_error_t err;
int flag;
err = ksba_cert_is_ca (cert, &flag, chainlen);
if (err)
return err;
if (!flag)
{
do_list (1, listmode, fp,_("issuer certificate is not marked as a CA"));
return gpg_error (GPG_ERR_BAD_CA_CERT);
}
return 0;
}
static int
check_cert_policy (ksba_cert_t cert, int listmode, FILE *fplist)
{
gpg_error_t err;
char *policies;
FILE *fp;
int any_critical;
err = ksba_cert_get_cert_policies (cert, &policies);
if (gpg_err_code (err) == GPG_ERR_NO_DATA)
return 0; /* no policy given */
if (err)
return err;
/* STRING is a line delimited list of certifiate policies as stored
in the certificate. The line itself is colon delimited where the
first field is the OID of the policy and the second field either
N or C for normal or critical extension */
if (opt.verbose > 1 && !listmode)
log_info ("certificate's policy list: %s\n", policies);
/* The check is very minimal but won't give false positives */
any_critical = !!strstr (policies, ":C");
if (!opt.policy_file)
{
xfree (policies);
if (any_critical)
{
do_list (1, listmode, fplist,
_("critical marked policy without configured policies"));
return gpg_error (GPG_ERR_NO_POLICY_MATCH);
}
return 0;
}
fp = fopen (opt.policy_file, "r");
if (!fp)
{
log_error ("failed to open `%s': %s\n",
opt.policy_file, strerror (errno));
xfree (policies);
/* With no critical policies this is only a warning */
if (!any_critical)
{
do_list (0, listmode, fplist,
_("note: non-critical certificate policy not allowed"));
return 0;
}
do_list (1, listmode, fplist,
_("certificate policy not allowed"));
return gpg_error (GPG_ERR_NO_POLICY_MATCH);
}
for (;;)
{
int c;
char *p, line[256];
char *haystack, *allowed;
/* read line */
do
{
if (!fgets (line, DIM(line)-1, fp) )
{
gpg_error_t tmperr = gpg_error (gpg_err_code_from_errno (errno));
xfree (policies);
if (feof (fp))
{
fclose (fp);
/* With no critical policies this is only a warning */
if (!any_critical)
{
do_list (0, listmode, fplist,
_("note: non-critical certificate policy not allowed"));
return 0;
}
do_list (1, listmode, fplist,
_("certificate policy not allowed"));
return gpg_error (GPG_ERR_NO_POLICY_MATCH);
}
fclose (fp);
return tmperr;
}
if (!*line || line[strlen(line)-1] != '\n')
{
/* eat until end of line */
while ( (c=getc (fp)) != EOF && c != '\n')
;
fclose (fp);
xfree (policies);
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 == '#');
/* parse line */
for (allowed=line; spacep (allowed); allowed++)
;
p = strpbrk (allowed, " :\n");
if (!*p || p == allowed)
{
fclose (fp);
xfree (policies);
return gpg_error (GPG_ERR_CONFIGURATION);
}
*p = 0; /* strip the rest of the line */
/* See whether we find ALLOWED (which is an OID) in POLICIES */
for (haystack=policies; (p=strstr (haystack, allowed)); haystack = p+1)
{
if ( !(p == policies || p[-1] == '\n') )
continue; /* Does not match the begin of a line. */
if (p[strlen (allowed)] != ':')
continue; /* The length does not match. */
/* Yep - it does match so return okay. */
fclose (fp);
xfree (policies);
return 0;
}
}
}
static void
find_up_store_certs_cb (void *cb_value, ksba_cert_t cert)
{
if (keydb_store_cert (cert, 1, NULL))
log_error ("error storing issuer certificate as ephemeral\n");
++*(int*)cb_value;
}
static int
find_up (KEYDB_HANDLE kh, ksba_cert_t cert, const char *issuer, int find_next)
{
ksba_name_t authid;
ksba_sexp_t authidno;
int rc = -1;
if (!ksba_cert_get_auth_key_id (cert, NULL, &authid, &authidno))
{
const char *s = ksba_name_enum (authid, 0);
if (s && *authidno)
{
rc = keydb_search_issuer_sn (kh, s, authidno);
if (rc)
keydb_search_reset (kh);
/* In case of an error try the ephemeral DB. We can't do
that in find-netx mode because we can't keep the search
state then. */
if (rc == -1 && !find_next)
{
int old = keydb_set_ephemeral (kh, 1);
if (!old)
{
rc = keydb_search_issuer_sn (kh, s, authidno);
if (rc)
keydb_search_reset (kh);
}
keydb_set_ephemeral (kh, old);
}
}
/* Print a note so that the user does not feel too helpless when
an issuer certificate was found and gpgsm prints BAD
signature because it is not the correct one. */
if (rc == -1)
{
log_info ("issuer certificate (#");
gpgsm_dump_serial (authidno);
log_printf ("/");
gpgsm_dump_string (s);
log_printf (") not found\n");
}
else if (rc)
log_error ("failed to find authorityKeyIdentifier: rc=%d\n", rc);
ksba_name_release (authid);
xfree (authidno);
/* Fixme: don't know how to do dirmngr lookup with serial+issuer. */
}
if (rc) /* not found via authorithyKeyIdentifier, try regular issuer name */
rc = keydb_search_subject (kh, issuer);
if (rc == -1 && !find_next)
{
/* Not found, lets see whether we have one in the ephemeral key DB. */
int old = keydb_set_ephemeral (kh, 1);
if (!old)
{
keydb_search_reset (kh);
rc = keydb_search_subject (kh, issuer);
}
keydb_set_ephemeral (kh, old);
}
if (rc == -1 && opt.auto_issuer_key_retrieve && !find_next)
{
STRLIST names = NULL;
int count = 0;
char *pattern;
const char *s;
if (opt.verbose)
log_info (_("looking up issuer at external location\n"));
/* dirmngr is confused about unknown attributes so as a quick
and ugly hack we locate the CN and use this and the
following. Fixme: we should have far better parsing in the
dirmngr. */
s = strstr (issuer, "CN=");
if (!s || s == issuer || s[-1] != ',')
s = issuer;
pattern = xtrymalloc (strlen (s)+2);
if (!pattern)
return OUT_OF_CORE (errno);
strcpy (stpcpy (pattern, "/"), s);
add_to_strlist (&names, pattern);
xfree (pattern);
rc = gpgsm_dirmngr_lookup (NULL, names, find_up_store_certs_cb, &count);
free_strlist (names);
if (opt.verbose)
log_info (_("number of issuers matching: %d\n"), count);
if (rc)
{
log_error ("external key lookup failed: %s\n", gpg_strerror (rc));
rc = -1;
}
else if (!count)
rc = -1;
else
{
int old;
/* The issuers are currently stored in the ephemeral key
DB, so we temporary switch to ephemeral mode. */
old = keydb_set_ephemeral (kh, 1);
keydb_search_reset (kh);
rc = keydb_search_subject (kh, issuer);
keydb_set_ephemeral (kh, old);
}
}
return rc;
}
/* Return the next certificate up in the chain starting at START.
Returns -1 when there are no more certificates. */
int
gpgsm_walk_cert_chain (ksba_cert_t start, ksba_cert_t *r_next)
{
int rc = 0;
char *issuer = NULL;
char *subject = NULL;
KEYDB_HANDLE kh = keydb_new (0);
*r_next = NULL;
if (!kh)
{
log_error (_("failed to allocated keyDB handle\n"));
rc = gpg_error (GPG_ERR_GENERAL);
goto leave;
}
issuer = ksba_cert_get_issuer (start, 0);
subject = ksba_cert_get_subject (start, 0);
if (!issuer)
{
log_error ("no issuer found in certificate\n");
rc = gpg_error (GPG_ERR_BAD_CERT);
goto leave;
}
if (!subject)
{
log_error ("no subject found in certificate\n");
rc = gpg_error (GPG_ERR_BAD_CERT);
goto leave;
}
if (!strcmp (issuer, subject))
{
rc = -1; /* we are at the root */
goto leave;
}
rc = find_up (kh, start, issuer, 0);
if (rc)
{
/* it is quite common not to have a certificate, so better don't
print an error here */
if (rc != -1 && opt.verbose > 1)
log_error ("failed to find issuer's certificate: rc=%d\n", rc);
rc = gpg_error (GPG_ERR_MISSING_CERT);
goto leave;
}
rc = keydb_get_cert (kh, r_next);
if (rc)
{
log_error ("failed to get cert: rc=%d\n", rc);
rc = gpg_error (GPG_ERR_GENERAL);
}
leave:
xfree (issuer);
xfree (subject);
keydb_release (kh);
return rc;
}
/* Check whether the CERT is a root certificate. Returns True if this
is the case. */
int
gpgsm_is_root_cert (ksba_cert_t cert)
{
char *issuer;
char *subject;
int yes;
issuer = ksba_cert_get_issuer (cert, 0);
subject = ksba_cert_get_subject (cert, 0);
yes = (issuer && subject && !strcmp (issuer, subject));
xfree (issuer);
xfree (subject);
return yes;
}
/* This is a helper for gpgsm_validate_chain. */
static gpg_error_t
is_cert_still_valid (ctrl_t ctrl, int lm, FILE *fp,
ksba_cert_t subject_cert, ksba_cert_t issuer_cert,
int *any_revoked, int *any_no_crl, int *any_crl_too_old)
{
if (!opt.no_crl_check || ctrl->use_ocsp)
{
gpg_error_t err;
err = gpgsm_dirmngr_isvalid (ctrl,
subject_cert, issuer_cert, ctrl->use_ocsp);
if (err)
{
/* Fixme: We should change the wording because we may
have used OCSP. */
switch (gpg_err_code (err))
{
case GPG_ERR_CERT_REVOKED:
do_list (1, lm, fp, _("certificate has been revoked"));
*any_revoked = 1;
/* Store that in the keybox so that key listings are
able to return the revoked flag. We don't care
about error, though. */
keydb_set_cert_flags (subject_cert, KEYBOX_FLAG_VALIDITY, 0,
VALIDITY_REVOKED);
break;
case GPG_ERR_NO_CRL_KNOWN:
do_list (1, lm, fp, _("no CRL found for certificate"));
*any_no_crl = 1;
break;
case GPG_ERR_CRL_TOO_OLD:
do_list (1, lm, fp, _("the available CRL is too old"));
if (!lm)
log_info (_("please make sure that the "
"\"dirmngr\" is properly installed\n"));
*any_crl_too_old = 1;
break;
default:
do_list (1, lm, fp, _("checking the CRL failed: %s"),
gpg_strerror (err));
return err;
}
}
}
return 0;
}
/* Validate a chain and optionally return the nearest expiration time
in R_EXPTIME. With LISTMODE set to 1 a special listmode is
activated where only information about the certificate is printed
to FP and no output is send to the usual log stream.
Defined flag bits: 0 - do not do any dirmngr isvalid checks.
*/
int
gpgsm_validate_chain (ctrl_t ctrl, ksba_cert_t cert, ksba_isotime_t r_exptime,
int listmode, FILE *fp, unsigned int flags)
{
int rc = 0, depth = 0, maxdepth;
char *issuer = NULL;
char *subject = NULL;
KEYDB_HANDLE kh = keydb_new (0);
ksba_cert_t subject_cert = NULL, issuer_cert = NULL;
ksba_isotime_t current_time;
ksba_isotime_t exptime;
int any_expired = 0;
int any_revoked = 0;
int any_no_crl = 0;
int any_crl_too_old = 0;
int any_no_policy_match = 0;
int lm = listmode;
gnupg_get_isotime (current_time);
if (r_exptime)
*r_exptime = 0;
*exptime = 0;
if (opt.no_chain_validation && !listmode)
{
log_info ("WARNING: bypassing certificate chain validation\n");
return 0;
}
if (!kh)
{
log_error (_("failed to allocated keyDB handle\n"));
rc = gpg_error (GPG_ERR_GENERAL);
goto leave;
}
if (DBG_X509 && !listmode)
gpgsm_dump_cert ("subject", cert);
subject_cert = cert;
maxdepth = 50;
for (;;)
{
xfree (issuer);
xfree (subject);
issuer = ksba_cert_get_issuer (subject_cert, 0);
subject = ksba_cert_get_subject (subject_cert, 0);
if (!issuer)
{
do_list (1, lm, fp, _("no issuer found in certificate"));
rc = gpg_error (GPG_ERR_BAD_CERT);
goto leave;
}
{
ksba_isotime_t not_before, not_after;
rc = ksba_cert_get_validity (subject_cert, 0, not_before);
if (!rc)
rc = ksba_cert_get_validity (subject_cert, 1, not_after);
if (rc)
{
do_list (1, lm, fp, _("certificate with invalid validity: %s"),
gpg_strerror (rc));
rc = gpg_error (GPG_ERR_BAD_CERT);
goto leave;
}
if (*not_after)
{
if (!*exptime)
gnupg_copy_time (exptime, not_after);
else if (strcmp (not_after, exptime) < 0 )
gnupg_copy_time (exptime, not_after);
}
if (*not_before && strcmp (current_time, not_before) < 0 )
{
do_list (1, lm, fp, _("certificate not yet valid"));
if (!lm)
{
log_info ("(valid from ");
gpgsm_dump_time (not_before);
log_printf (")\n");
}
rc = gpg_error (GPG_ERR_CERT_TOO_YOUNG);
goto leave;
}
if (*not_after && strcmp (current_time, not_after) > 0 )
{
do_list (opt.ignore_expiration?0:1, lm, fp,
_("certificate has expired"));
if (!lm)
{
log_info ("(expired at ");
gpgsm_dump_time (not_after);
log_printf (")\n");
}
if (opt.ignore_expiration)
log_info ("WARNING: ignoring expiration\n");
else
any_expired = 1;
}
}
rc = unknown_criticals (subject_cert, listmode, fp);
if (rc)
goto leave;
if (!opt.no_policy_check)
{
rc = check_cert_policy (subject_cert, listmode, fp);
if (gpg_err_code (rc) == GPG_ERR_NO_POLICY_MATCH)
{
any_no_policy_match = 1;
rc = 1;
}
else if (rc)
goto leave;
}
/* Is this a self-signed certificate? */
if (subject && !strcmp (issuer, subject))
{ /* Yes. */
if (gpgsm_check_cert_sig (subject_cert, subject_cert) )
{
do_list (1, lm, fp,
_("selfsigned certificate has a BAD signature"));
rc = gpg_error (depth? GPG_ERR_BAD_CERT_CHAIN
: GPG_ERR_BAD_CERT);
goto leave;
}
rc = allowed_ca (subject_cert, NULL, listmode, fp);
if (rc)
goto leave;
rc = gpgsm_agent_istrusted (ctrl, subject_cert);
if (!rc)
;
else if (gpg_err_code (rc) == GPG_ERR_NOT_TRUSTED)
{
do_list (0, lm, fp, _("root certificate is not marked trusted"));
if (!lm)
{
int rc2;
char *fpr = gpgsm_get_fingerprint_string (subject_cert,
GCRY_MD_SHA1);
log_info (_("fingerprint=%s\n"), fpr? fpr : "?");
xfree (fpr);
rc2 = gpgsm_agent_marktrusted (ctrl, subject_cert);
if (!rc2)
{
log_info (_("root certificate has now"
" been marked as trusted\n"));
rc = 0;
}
else
{
gpgsm_dump_cert ("issuer", subject_cert);
log_info ("after checking the fingerprint, you may want "
"to add it manually to the list of trusted "
"certificates.\n");
}
}
}
else
{
log_error (_("checking the trust list failed: %s\n"),
gpg_strerror (rc));
}
if (rc)
goto leave;
/* Check for revocations etc. */
if ((flags & 1))
rc = 0;
else
rc = is_cert_still_valid (ctrl, lm, fp,
subject_cert, subject_cert,
&any_revoked, &any_no_crl,
&any_crl_too_old);
if (rc)
goto leave;
break; /* Okay: a self-signed certicate is an end-point. */
}
depth++;
if (depth > maxdepth)
{
do_list (1, lm, fp, _("certificate chain too long\n"));
rc = gpg_error (GPG_ERR_BAD_CERT_CHAIN);
goto leave;
}
/* find the next cert up the tree */
keydb_search_reset (kh);
rc = find_up (kh, subject_cert, issuer, 0);
if (rc)
{
if (rc == -1)
{
do_list (0, lm, fp, _("issuer certificate not found"));
if (!lm)
{
log_info ("issuer certificate: #/");
gpgsm_dump_string (issuer);
log_printf ("\n");
}
}
else
log_error ("failed to find issuer's certificate: rc=%d\n", rc);
rc = gpg_error (GPG_ERR_MISSING_CERT);
goto leave;
}
ksba_cert_release (issuer_cert); issuer_cert = NULL;
rc = keydb_get_cert (kh, &issuer_cert);
if (rc)
{
log_error ("failed to get cert: rc=%d\n", rc);
rc = gpg_error (GPG_ERR_GENERAL);
goto leave;
}
try_another_cert:
if (DBG_X509)
{
log_debug ("got issuer's certificate:\n");
gpgsm_dump_cert ("issuer", issuer_cert);
}
rc = gpgsm_check_cert_sig (issuer_cert, subject_cert);
if (rc)
{
do_list (0, lm, fp, _("certificate has a BAD signature"));
if (gpg_err_code (rc) == GPG_ERR_BAD_SIGNATURE)
{
/* We now try to find other issuer certificates which
might have been used. This is rquired because some
CAs are reusing the issuer and subject DN for new
root certificates. */
rc = find_up (kh, subject_cert, issuer, 1);
if (!rc)
{
ksba_cert_t tmp_cert;
rc = keydb_get_cert (kh, &tmp_cert);
if (rc || !compare_certs (issuer_cert, tmp_cert))
{
/* The find next did not work or returned an
identical certificate. We better stop here
to avoid infinite checks. */
rc = gpg_error (GPG_ERR_BAD_SIGNATURE);
ksba_cert_release (tmp_cert);
}
else
{
do_list (0, lm, fp, _("found another possible matching "
"CA certificate - trying again"));
ksba_cert_release (issuer_cert);
issuer_cert = tmp_cert;
goto try_another_cert;
}
}
}
/* We give a more descriptive error code than the one
returned from the signature checking. */
rc = gpg_error (GPG_ERR_BAD_CERT_CHAIN);
goto leave;
}
{
int chainlen;
rc = allowed_ca (issuer_cert, &chainlen, listmode, fp);
if (rc)
goto leave;
if (chainlen >= 0 && (depth - 1) > chainlen)
{
do_list (1, lm, fp,
_("certificate chain longer than allowed by CA (%d)"),
chainlen);
rc = gpg_error (GPG_ERR_BAD_CERT_CHAIN);
goto leave;
}
}
if (!listmode)
{
rc = gpgsm_cert_use_cert_p (issuer_cert);
if (rc)
{
char numbuf[50];
sprintf (numbuf, "%d", rc);
gpgsm_status2 (ctrl, STATUS_ERROR, "certcert.issuer.keyusage",
numbuf, NULL);
goto leave;
}
}
/* Check for revocations etc. */
if ((flags & 1))
rc = 0;
else
rc = is_cert_still_valid (ctrl, lm, fp,
subject_cert, issuer_cert,
&any_revoked, &any_no_crl, &any_crl_too_old);
if (rc)
goto leave;
if (opt.verbose && !listmode)
log_info ("certificate is good\n");
keydb_search_reset (kh);
subject_cert = issuer_cert;
issuer_cert = NULL;
}
if (!listmode)
{
if (opt.no_policy_check)
log_info ("policies not checked due to %s option\n",
"--disable-policy-checks");
if (opt.no_crl_check && !ctrl->use_ocsp)
log_info ("CRLs not checked due to %s option\n",
"--disable-crl-checks");
}
if (!rc)
{ /* If we encountered an error somewhere during the checks, set
the error code to the most critical one */
if (any_revoked)
rc = gpg_error (GPG_ERR_CERT_REVOKED);
else if (any_no_crl)
rc = gpg_error (GPG_ERR_NO_CRL_KNOWN);
else if (any_crl_too_old)
rc = gpg_error (GPG_ERR_CRL_TOO_OLD);
else if (any_no_policy_match)
rc = gpg_error (GPG_ERR_NO_POLICY_MATCH);
else if (any_expired)
rc = gpg_error (GPG_ERR_CERT_EXPIRED);
}
leave:
if (r_exptime)
gnupg_copy_time (r_exptime, exptime);
xfree (issuer);
keydb_release (kh);
ksba_cert_release (issuer_cert);
if (subject_cert != cert)
ksba_cert_release (subject_cert);
return rc;
}
/* Check that the given certificate is valid but DO NOT check any
constraints. We assume that the issuers certificate is already in
the DB and that this one is valid; which it should be because it
has been checked using this function. */
int
gpgsm_basic_cert_check (ksba_cert_t cert)
{
int rc = 0;
char *issuer = NULL;
char *subject = NULL;
KEYDB_HANDLE kh = keydb_new (0);
ksba_cert_t issuer_cert = NULL;
if (opt.no_chain_validation)
{
log_info ("WARNING: bypassing basic certificate checks\n");
return 0;
}
if (!kh)
{
log_error (_("failed to allocated keyDB handle\n"));
rc = gpg_error (GPG_ERR_GENERAL);
goto leave;
}
issuer = ksba_cert_get_issuer (cert, 0);
subject = ksba_cert_get_subject (cert, 0);
if (!issuer)
{
log_error ("no issuer found in certificate\n");
rc = gpg_error (GPG_ERR_BAD_CERT);
goto leave;
}
if (subject && !strcmp (issuer, subject))
{
- if (gpgsm_check_cert_sig (cert, cert) )
+ rc = gpgsm_check_cert_sig (cert, cert);
+ if (rc)
{
- log_error ("selfsigned certificate has a BAD signature\n");
+ log_error ("selfsigned certificate has a BAD signature: %s\n",
+ gpg_strerror (rc));
rc = gpg_error (GPG_ERR_BAD_CERT);
goto leave;
}
}
else
{
/* find the next cert up the tree */
keydb_search_reset (kh);
rc = find_up (kh, cert, issuer, 0);
if (rc)
{
if (rc == -1)
{
log_info ("issuer certificate (#/");
gpgsm_dump_string (issuer);
log_printf (") not found\n");
}
else
log_error ("failed to find issuer's certificate: rc=%d\n", rc);
rc = gpg_error (GPG_ERR_MISSING_CERT);
goto leave;
}
ksba_cert_release (issuer_cert); issuer_cert = NULL;
rc = keydb_get_cert (kh, &issuer_cert);
if (rc)
{
log_error ("failed to get cert: rc=%d\n", rc);
rc = gpg_error (GPG_ERR_GENERAL);
goto leave;
}
- if (gpgsm_check_cert_sig (issuer_cert, cert) )
+ rc = gpgsm_check_cert_sig (issuer_cert, cert);
+ if (rc)
{
- log_error ("certificate has a BAD signature\n");
+ log_error ("certificate has a BAD signature: %s\n",
+ gpg_strerror (rc));
rc = gpg_error (GPG_ERR_BAD_CERT);
goto leave;
}
if (opt.verbose)
log_info ("certificate is good\n");
}
leave:
xfree (issuer);
keydb_release (kh);
ksba_cert_release (issuer_cert);
return rc;
}
diff --git a/sm/certcheck.c b/sm/certcheck.c
index b5ed9914a..4f667cbbe 100644
--- a/sm/certcheck.c
+++ b/sm/certcheck.c
@@ -1,303 +1,357 @@
/* certcheck.c - check one certificate
- * Copyright (C) 2001, 2003 Free Software Foundation, Inc.
+ * Copyright (C) 2001, 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#include <config.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <time.h>
#include <assert.h>
#include "gpgsm.h"
#include <gcrypt.h>
#include <ksba.h>
#include "keydb.h"
#include "i18n.h"
static int
-do_encode_md (gcry_md_hd_t md, int algo, unsigned int nbits,
+do_encode_md (gcry_md_hd_t md, int algo, int pkalgo, unsigned int nbits,
gcry_mpi_t *r_val)
{
- int nframe = (nbits+7) / 8;
- byte *frame;
- int i, n;
- byte asn[100];
- size_t asnlen;
- size_t len;
-
- asnlen = DIM(asn);
- if (gcry_md_algo_info (algo, GCRYCTL_GET_ASNOID, asn, &asnlen))
+ int n, nframe;
+ unsigned char *frame;
+
+ if (pkalgo == GCRY_PK_DSA)
{
- log_error ("no object identifier for algo %d\n", algo);
- return gpg_error (GPG_ERR_INTERNAL);
+ nframe = gcry_md_get_algo_dlen (algo);
+ if (nframe != 20)
+ {
+ log_error (_("DSA requires the use of a 160 bit hash algorithm\n"));
+ return gpg_error (GPG_ERR_INTERNAL);
+ }
+ frame = xtrymalloc (nframe);
+ if (!frame)
+ return OUT_OF_CORE (errno);
+ memcpy (frame, gcry_md_read (md, algo), nframe);
+ n = nframe;
}
-
- len = gcry_md_get_algo_dlen (algo);
-
- if ( len + asnlen + 4 > nframe )
+ else
{
- log_error ("can't encode a %d bit MD into a %d bits frame\n",
- (int)(len*8), (int)nbits);
- return gpg_error (GPG_ERR_INTERNAL);
+ int i;
+ unsigned char asn[100];
+ size_t asnlen;
+ size_t len;
+
+ nframe = (nbits+7) / 8;
+
+ 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);
+ }
+
+ len = gcry_md_get_algo_dlen (algo);
+
+ if ( len + asnlen + 4 > nframe )
+ {
+ log_error ("can't encode a %d bit MD into a %d bits frame\n",
+ (int)(len*8), (int)nbits);
+ return gpg_error (GPG_ERR_INTERNAL);
+ }
+
+ /* We encode the MD in this way:
+ *
+ * 0 A PAD(n bytes) 0 ASN(asnlen bytes) MD(len bytes)
+ *
+ * PAD consists of FF bytes.
+ */
+ frame = xtrymalloc (nframe);
+ if (!frame)
+ return OUT_OF_CORE (errno);
+ n = 0;
+ frame[n++] = 0;
+ frame[n++] = 1; /* block type */
+ i = nframe - len - asnlen -3 ;
+ assert ( i > 1 );
+ memset ( frame+n, 0xff, i ); n += i;
+ frame[n++] = 0;
+ memcpy ( frame+n, asn, asnlen ); n += asnlen;
+ memcpy ( frame+n, gcry_md_read(md, algo), len ); n += len;
+ assert ( n == nframe );
}
-
- /* We encode the MD in this way:
- *
- * 0 A PAD(n bytes) 0 ASN(asnlen bytes) MD(len bytes)
- *
- * PAD consists of FF bytes.
- */
- frame = xtrymalloc (nframe);
- if (!frame)
- return OUT_OF_CORE (errno);
- n = 0;
- frame[n++] = 0;
- frame[n++] = 1; /* block type */
- i = nframe - len - asnlen -3 ;
- assert ( i > 1 );
- memset ( frame+n, 0xff, i ); n += i;
- frame[n++] = 0;
- memcpy ( frame+n, asn, asnlen ); n += asnlen;
- memcpy ( frame+n, gcry_md_read(md, algo), len ); n += len;
- assert ( n == nframe );
if (DBG_X509)
{
int j;
log_debug ("encoded hash:");
for (j=0; j < nframe; j++)
log_printf (" %02X", frame[j]);
log_printf ("\n");
}
gcry_mpi_scan (r_val, GCRYMPI_FMT_USG, frame, n, &nframe);
xfree (frame);
return 0;
}
+/* Return the public key algorithm id from the S-expression PKEY.
+ FIXME: libgcrypt should provide such a function. Note that this
+ implementation uses the names as used by libksba. */
+static int
+pk_algo_from_sexp (gcry_sexp_t pkey)
+{
+ gcry_sexp_t l1, l2;
+ const char *name;
+ size_t n;
+ int algo;
+
+ l1 = gcry_sexp_find_token (pkey, "public-key", 0);
+ if (!l1)
+ return 0; /* Not found. */
+ l2 = gcry_sexp_cadr (l1);
+ gcry_sexp_release (l1);
+
+ name = gcry_sexp_nth_data (l2, 0, &n);
+ if (!name)
+ algo = 0; /* Not found. */
+ else if (n==3 && !memcmp (name, "rsa", 3))
+ algo = GCRY_PK_RSA;
+ else if (n==3 && !memcmp (name, "dsa", 3))
+ algo = GCRY_PK_DSA;
+ else if (n==13 && !memcmp (name, "ambiguous-rsa", 13))
+ algo = GCRY_PK_RSA;
+ else
+ algo = 0;
+ gcry_sexp_release (l2);
+ return algo;
+}
+
/*
Check the signature on CERT using the ISSUER-CERT. This function
does only test the cryptographic signature and nothing else. It is
assumed that the ISSUER_CERT is valid. */
int
gpgsm_check_cert_sig (ksba_cert_t issuer_cert, ksba_cert_t cert)
{
const char *algoid;
gcry_md_hd_t md;
int rc, algo;
gcry_mpi_t frame;
ksba_sexp_t p;
size_t n;
gcry_sexp_t s_sig, s_hash, s_pkey;
algo = gcry_md_map_name ( (algoid=ksba_cert_get_digest_algo (cert)));
if (!algo)
{
log_error ("unknown hash algorithm `%s'\n", algoid? algoid:"?");
return gpg_error (GPG_ERR_GENERAL);
}
rc = gcry_md_open (&md, algo, 0);
if (rc)
{
log_error ("md_open failed: %s\n", gpg_strerror (rc));
return rc;
}
if (DBG_HASHING)
gcry_md_start_debug (md, "hash.cert");
rc = ksba_cert_hash (cert, 1, HASH_FNC, md);
if (rc)
{
log_error ("ksba_cert_hash failed: %s\n", gpg_strerror (rc));
gcry_md_close (md);
return rc;
}
gcry_md_final (md);
p = ksba_cert_get_sig_val (cert);
n = gcry_sexp_canon_len (p, 0, NULL, NULL);
if (!n)
{
log_error ("libksba did not return a proper S-Exp\n");
gcry_md_close (md);
ksba_free (p);
return gpg_error (GPG_ERR_BUG);
}
if (DBG_X509)
{
int j;
log_debug ("signature value:");
for (j=0; j < n; j++)
log_printf (" %02X", p[j]);
log_printf ("\n");
}
rc = gcry_sexp_sscan ( &s_sig, NULL, p, n);
ksba_free (p);
if (rc)
{
log_error ("gcry_sexp_scan failed: %s\n", gpg_strerror (rc));
gcry_md_close (md);
return rc;
}
p = ksba_cert_get_public_key (issuer_cert);
n = gcry_sexp_canon_len (p, 0, NULL, NULL);
if (!n)
{
log_error ("libksba did not return a proper S-Exp\n");
gcry_md_close (md);
ksba_free (p);
gcry_sexp_release (s_sig);
return gpg_error (GPG_ERR_BUG);
}
rc = gcry_sexp_sscan ( &s_pkey, NULL, p, n);
ksba_free (p);
if (rc)
{
log_error ("gcry_sexp_scan failed: %s\n", gpg_strerror (rc));
gcry_md_close (md);
gcry_sexp_release (s_sig);
return rc;
}
- rc = do_encode_md (md, algo, gcry_pk_get_nbits (s_pkey), &frame);
+ rc = do_encode_md (md, algo, pk_algo_from_sexp (s_pkey),
+ gcry_pk_get_nbits (s_pkey), &frame);
if (rc)
{
gcry_md_close (md);
gcry_sexp_release (s_sig);
gcry_sexp_release (s_pkey);
return rc;
}
/* put hash into the S-Exp s_hash */
if ( gcry_sexp_build (&s_hash, NULL, "%m", frame) )
BUG ();
gcry_mpi_release (frame);
rc = gcry_pk_verify (s_sig, s_hash, s_pkey);
if (DBG_CRYPTO)
log_debug ("gcry_pk_verify: %s\n", gpg_strerror (rc));
gcry_md_close (md);
gcry_sexp_release (s_sig);
gcry_sexp_release (s_hash);
gcry_sexp_release (s_pkey);
return rc;
}
int
gpgsm_check_cms_signature (ksba_cert_t cert, ksba_const_sexp_t sigval,
gcry_md_hd_t md, int algo)
{
int rc;
ksba_sexp_t p;
gcry_mpi_t frame;
gcry_sexp_t s_sig, s_hash, s_pkey;
size_t n;
n = gcry_sexp_canon_len (sigval, 0, NULL, NULL);
if (!n)
{
log_error ("libksba did not return a proper S-Exp\n");
return gpg_error (GPG_ERR_BUG);
}
rc = gcry_sexp_sscan (&s_sig, NULL, sigval, n);
if (rc)
{
log_error ("gcry_sexp_scan failed: %s\n", gpg_strerror (rc));
return rc;
}
p = ksba_cert_get_public_key (cert);
n = gcry_sexp_canon_len (p, 0, NULL, NULL);
if (!n)
{
log_error ("libksba did not return a proper S-Exp\n");
ksba_free (p);
gcry_sexp_release (s_sig);
return gpg_error (GPG_ERR_BUG);
}
if (DBG_X509)
log_printhex ("public key: ", p, n);
rc = gcry_sexp_sscan ( &s_pkey, NULL, p, n);
ksba_free (p);
if (rc)
{
log_error ("gcry_sexp_scan failed: %s\n", gpg_strerror (rc));
gcry_sexp_release (s_sig);
return rc;
}
- rc = do_encode_md (md, algo, gcry_pk_get_nbits (s_pkey), &frame);
+ rc = do_encode_md (md, algo, pk_algo_from_sexp (s_pkey),
+ gcry_pk_get_nbits (s_pkey), &frame);
if (rc)
{
gcry_sexp_release (s_sig);
gcry_sexp_release (s_pkey);
return rc;
}
/* put hash into the S-Exp s_hash */
if ( gcry_sexp_build (&s_hash, NULL, "%m", frame) )
BUG ();
gcry_mpi_release (frame);
rc = gcry_pk_verify (s_sig, s_hash, s_pkey);
if (DBG_CRYPTO)
log_debug ("gcry_pk_verify: %s\n", gpg_strerror (rc));
gcry_sexp_release (s_sig);
gcry_sexp_release (s_hash);
gcry_sexp_release (s_pkey);
return rc;
}
int
gpgsm_create_cms_signature (ctrl_t ctrl, ksba_cert_t cert,
gcry_md_hd_t md, int mdalgo, char **r_sigval)
{
int rc;
char *grip, *desc;
size_t siglen;
grip = gpgsm_get_keygrip_hexstring (cert);
if (!grip)
return gpg_error (GPG_ERR_BAD_CERT);
desc = gpgsm_format_keydesc (cert);
rc = gpgsm_agent_pksign (ctrl, grip, desc, gcry_md_read(md, mdalgo),
gcry_md_get_algo_dlen (mdalgo), mdalgo,
r_sigval, &siglen);
xfree (desc);
xfree (grip);
return rc;
}
diff --git a/sm/gpgsm.c b/sm/gpgsm.c
index 5fb80a0de..3331537b1 100644
--- a/sm/gpgsm.c
+++ b/sm/gpgsm.c
@@ -1,1703 +1,1707 @@
/* gpgsm.c - GnuPG for S/MIME
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#include <config.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <unistd.h>
#include <fcntl.h>
#include "gpgsm.h"
#include <gcrypt.h>
#include <assuan.h> /* malloc hooks */
#include "../kbx/keybox.h" /* malloc hooks */
#include "i18n.h"
#include "keydb.h"
#include "sysutils.h"
enum cmd_and_opt_values {
aNull = 0,
oArmor = 'a',
aDetachedSign = 'b',
aSym = 'c',
aDecrypt = 'd',
aEncr = 'e',
oInteractive = 'i',
aListKeys = 'k',
aListSecretKeys = 'K',
oDryRun = 'n',
oOutput = 'o',
oQuiet = 'q',
oRecipient = 'r',
aSign = 's',
oTextmodeShort= 't',
oUser = 'u',
oVerbose = 'v',
oCompress = 'z',
oNotation = 'N',
oBatch = 500,
aClearsign,
aStore,
aKeygen,
aSignEncr,
aSignKey,
aLSignKey,
aListPackets,
aEditKey,
aDeleteKey,
aImport,
aVerify,
aVerifyFiles,
aListExternalKeys,
aListSigs,
aSendKeys,
aRecvKeys,
aExport,
aExportSecretKeyP12,
aCheckKeys, /* nyi */
aServer,
aLearnCard,
aCallDirmngr,
aCallProtectTool,
aPasswd,
aGPGConfList,
aDumpKeys,
aDumpSecretKeys,
aDumpExternalKeys,
aKeydbClearSomeCertFlags,
oOptions,
oDebug,
oDebugLevel,
oDebugAll,
oDebugWait,
oDebugAllowCoreDump,
oDebugNoChainValidation,
oDebugIgnoreExpiration,
+ oFixedPassphrase,
oLogFile,
oEnableSpecialFilenames,
oAgentProgram,
oDisplay,
oTTYname,
oTTYtype,
oLCctype,
oLCmessages,
oDirmngrProgram,
oProtectToolProgram,
oFakedSystemTime,
oAssumeArmor,
oAssumeBase64,
oAssumeBinary,
oBase64,
oNoArmor,
oDisableCRLChecks,
oEnableCRLChecks,
oForceCRLRefresh,
oDisableOCSP,
oEnableOCSP,
oIncludeCerts,
oPolicyFile,
oDisablePolicyChecks,
oEnablePolicyChecks,
oAutoIssuerKeyRetrieve,
oTextmode,
oFingerprint,
oWithFingerprint,
oWithMD5Fingerprint,
oAnswerYes,
oAnswerNo,
oKeyring,
oSecretKeyring,
oDefaultKey,
oDefRecipient,
oDefRecipientSelf,
oNoDefRecipient,
oStatusFD,
oNoComment,
oNoVersion,
oEmitVersion,
oCompletesNeeded,
oMarginalsNeeded,
oMaxCertDepth,
oLoadExtension,
oRFC1991,
oOpenPGP,
oCipherAlgo,
oDigestAlgo,
oCompressAlgo,
oCommandFD,
oNoVerbose,
oTrustDBName,
oNoSecmemWarn,
oNoDefKeyring,
oNoGreeting,
oNoTTY,
oNoOptions,
oNoBatch,
oHomedir,
oWithColons,
oWithKeyData,
oWithValidation,
oWithEphemeralKeys,
oSkipVerify,
oCompressKeys,
oCompressSigs,
oAlwaysTrust,
oRunAsShmCP,
oSetFilename,
oSetPolicyURL,
oUseEmbeddedFilename,
oComment,
oDefaultComment,
oThrowKeyid,
oForceV3Sigs,
oForceMDC,
oS2KMode,
oS2KDigest,
oS2KCipher,
oCharset,
oNotDashEscaped,
oEscapeFrom,
oLockOnce,
oLockMultiple,
oLockNever,
oKeyServer,
oEncryptTo,
oNoEncryptTo,
oLoggerFD,
oUtf8Strings,
oNoUtf8Strings,
oDisableCipherAlgo,
oDisablePubkeyAlgo,
oAllowNonSelfsignedUID,
oAllowFreeformUID,
oNoLiteral,
oSetFilesize,
oHonorHttpProxy,
oFastListMode,
oListOnly,
oIgnoreTimeConflict,
oNoRandomSeedFile,
oNoAutoKeyRetrieve,
oUseAgent,
oMergeOnly,
oTryAllSecrets,
oTrustedKey,
oEmuMDEncodeBug,
aDummy
};
static ARGPARSE_OPTS opts[] = {
{ 300, NULL, 0, N_("@Commands:\n ") },
{ aSign, "sign", 256, N_("|[FILE]|make a signature")},
{ aClearsign, "clearsign", 256, N_("|[FILE]|make a clear text signature") },
{ aDetachedSign, "detach-sign", 256, N_("make a detached signature")},
{ aEncr, "encrypt", 256, N_("encrypt data")},
{ aSym, "symmetric", 256, N_("encryption only with symmetric cipher")},
{ aDecrypt, "decrypt", 256, N_("decrypt data (default)")},
{ aVerify, "verify" , 256, N_("verify a signature")},
{ aVerifyFiles, "verify-files" , 256, "@" },
{ aListKeys, "list-keys", 256, N_("list keys")},
{ aListExternalKeys, "list-external-keys", 256, N_("list external keys")},
{ aListSecretKeys, "list-secret-keys", 256, N_("list secret keys")},
{ aListSigs, "list-sigs", 256, N_("list certificate chain")},
{ aListSigs, "check-sigs",256, "@"},
{ oFingerprint, "fingerprint", 256, N_("list keys and fingerprints")},
{ aKeygen, "gen-key", 256, N_("generate a new key pair")},
{ aDeleteKey, "delete-key",256, N_("remove key from the public keyring")},
{ aSendKeys, "send-keys" , 256, N_("export keys to a key server") },
{ aRecvKeys, "recv-keys" , 256, N_("import keys from a key server") },
{ aImport, "import", 256 , N_("import certificates")},
{ aExport, "export", 256 , N_("export certificates")},
{ aLearnCard, "learn-card", 256 ,N_("register a smartcard")},
{ aServer, "server", 256, N_("run in server mode")},
{ aCallDirmngr, "call-dirmngr", 256, N_("pass a command to the dirmngr")},
{ aCallProtectTool, "call-protect-tool", 256,
N_("invoke gpg-protect-tool")},
{ aPasswd, "passwd", 256, N_("change a passphrase")},
{ aGPGConfList, "gpgconf-list", 256, "@" },
{ aDumpKeys, "dump-keys", 256, "@"},
{ aDumpExternalKeys, "dump-external-keys", 256, "@"},
{ aDumpSecretKeys, "dump-secret-keys", 256, "@"},
{ aKeydbClearSomeCertFlags, "keydb-clear-some-cert-flags", 256, "@"},
{ 301, NULL, 0, N_("@\nOptions:\n ") },
{ oArmor, "armor", 0, N_("create ascii armored output")},
{ oArmor, "armour", 0, "@" },
{ oBase64, "base64", 0, N_("create base-64 encoded output")},
{ oAssumeArmor, "assume-armor", 0, N_("assume input is in PEM format")},
{ oAssumeBase64, "assume-base64", 0,
N_("assume input is in base-64 format")},
{ oAssumeBinary, "assume-binary", 0,
N_("assume input is in binary format")},
{ oRecipient, "recipient", 2, N_("|NAME|encrypt for NAME")},
{ oDisableCRLChecks, "disable-crl-checks", 0, N_("never consult a CRL")},
{ oEnableCRLChecks, "enable-crl-checks", 0, "@"},
{ oForceCRLRefresh, "force-crl-refresh", 0, "@"},
{ oDisableOCSP, "disable-ocsp", 0, "@" },
{ oEnableOCSP, "enable-ocsp", 0, N_("check validity using OCSP")},
{ oIncludeCerts, "include-certs", 1,
N_("|N|number of certificates to include") },
{ oPolicyFile, "policy-file", 2,
N_("|FILE|take policy information from FILE") },
{ oDisablePolicyChecks, "disable-policy-checks", 0,
N_("do not check certificate policies")},
{ oEnablePolicyChecks, "enable-policy-checks", 0, "@"},
{ oAutoIssuerKeyRetrieve, "auto-issuer-key-retrieve", 0,
N_("fetch missing issuer certificates")},
#if 0
{ oDefRecipient, "default-recipient" ,2,
N_("|NAME|use NAME as default recipient")},
{ oDefRecipientSelf, "default-recipient-self" ,0,
N_("use the default key as default recipient")},
{ oNoDefRecipient, "no-default-recipient", 0, "@" },
#endif
{ oEncryptTo, "encrypt-to", 2, "@" },
{ oNoEncryptTo, "no-encrypt-to", 0, "@" },
{ oUser, "local-user",2, N_("use this user-id to sign or decrypt")},
#if 0
{ oCompress, NULL, 1, N_("|N|set compress level N (0 disables)") },
{ oTextmodeShort, NULL, 0, "@"},
{ oTextmode, "textmode", 0, N_("use canonical text mode")},
#endif
{ oOutput, "output", 2, N_("use as output file")},
{ oVerbose, "verbose", 0, N_("verbose") },
{ oQuiet, "quiet", 0, N_("be somewhat more quiet") },
{ oNoTTY, "no-tty", 0, N_("don't use the terminal at all") },
{ oLogFile, "log-file" ,2, N_("use a log file for the server")},
#if 0
{ oForceV3Sigs, "force-v3-sigs", 0, N_("force v3 signatures") },
{ oForceMDC, "force-mdc", 0, N_("always use a MDC for encryption") },
#endif
{ oDryRun, "dry-run", 0, N_("do not make any changes") },
/*{ oInteractive, "interactive", 0, N_("prompt before overwriting") }, */
/*{ oUseAgent, "use-agent",0, N_("use the gpg-agent")},*/
{ oBatch, "batch", 0, N_("batch mode: never ask")},
{ oAnswerYes, "yes", 0, N_("assume yes on most questions")},
{ oAnswerNo, "no", 0, N_("assume no on most questions")},
{ oKeyring, "keyring" ,2, N_("add this keyring to the list of keyrings")},
{ oSecretKeyring, "secret-keyring" ,2, N_("add this secret keyring to the list")},
{ oDefaultKey, "default-key" ,2, N_("|NAME|use NAME as default secret key")},
{ oKeyServer, "keyserver",2, N_("|HOST|use this keyserver to lookup keys")},
{ oCharset, "charset" , 2, N_("|NAME|set terminal charset to NAME") },
{ oOptions, "options" , 2, N_("read options from file")},
{ oDebug, "debug" ,4|16, "@"},
{ oDebugLevel, "debug-level" ,2, "@"},
{ oDebugAll, "debug-all" ,0, "@"},
{ oDebugWait, "debug-wait" ,1, "@"},
{ oDebugAllowCoreDump, "debug-allow-core-dump", 0, "@" },
{ oDebugNoChainValidation, "debug-no-chain-validation", 0, "@"},
{ oDebugIgnoreExpiration, "debug-ignore-expiration", 0, "@"},
+ { oFixedPassphrase, "fixed-passphrase", 2, "@"},
{ oStatusFD, "status-fd" ,1, N_("|FD|write status info to this FD") },
{ aDummy, "no-comment", 0, "@"},
{ aDummy, "completes-needed", 1, "@"},
{ aDummy, "marginals-needed", 1, "@"},
{ oMaxCertDepth, "max-cert-depth", 1, "@" },
{ aDummy, "trusted-key", 2, "@"},
{ oLoadExtension, "load-extension" ,2,
N_("|FILE|load extension module FILE")},
{ aDummy, "rfc1991", 0, "@"},
{ aDummy, "openpgp", 0, "@"},
{ aDummy, "s2k-mode", 1, "@"},
{ aDummy, "s2k-digest-algo",2, "@"},
{ aDummy, "s2k-cipher-algo",2, "@"},
{ oCipherAlgo, "cipher-algo", 2 , N_("|NAME|use cipher algorithm NAME")},
{ oDigestAlgo, "digest-algo", 2 ,
N_("|NAME|use message digest algorithm NAME")},
#if 0
{ oCompressAlgo, "compress-algo", 1 , N_("|N|use compress algorithm N")},
#endif
{ aDummy, "throw-keyid", 0, "@"},
{ aDummy, "notation-data", 2, "@"},
{ aExportSecretKeyP12, "export-secret-key-p12", 256, "@"},
{ 302, NULL, 0, N_(
"@\n(See the man page for a complete listing of all commands and options)\n"
)},
{ 303, NULL, 0, N_("@\nExamples:\n\n"
" -se -r Bob [file] sign and encrypt for user Bob\n"
" --clearsign [file] make a clear text signature\n"
" --detach-sign [file] make a detached signature\n"
" --list-keys [names] show keys\n"
" --fingerprint [names] show fingerprints\n" ) },
/* hidden options */
{ oNoVerbose, "no-verbose", 0, "@"},
{ oEnableSpecialFilenames, "enable-special-filenames", 0, "@" },
{ oTrustDBName, "trustdb-name", 2, "@" },
{ oNoSecmemWarn, "no-secmem-warning", 0, "@" },
{ oNoArmor, "no-armor", 0, "@"},
{ oNoArmor, "no-armour", 0, "@"},
{ oNoDefKeyring, "no-default-keyring", 0, "@" },
{ oNoGreeting, "no-greeting", 0, "@" },
{ oNoOptions, "no-options", 0, "@" }, /* shortcut for --options /dev/null */
{ oHomedir, "homedir", 2, "@" }, /* defaults to "~/.gnupg" */
{ oAgentProgram, "agent-program", 2 , "@" },
{ oDisplay, "display", 2, "@" },
{ oTTYname, "ttyname", 2, "@" },
{ oTTYtype, "ttytype", 2, "@" },
{ oLCctype, "lc-ctype", 2, "@" },
{ oLCmessages, "lc-messages", 2, "@" },
{ oDirmngrProgram, "dirmngr-program", 2 , "@" },
{ oProtectToolProgram, "protect-tool-program", 2 , "@" },
{ oFakedSystemTime, "faked-system-time", 4, "@" }, /* (epoch time) */
{ oNoBatch, "no-batch", 0, "@" },
{ oWithColons, "with-colons", 0, "@"},
{ oWithKeyData,"with-key-data", 0, "@"},
{ oWithValidation, "with-validation", 0, "@"},
{ oWithMD5Fingerprint, "with-md5-fingerprint", 0, "@"},
{ oWithEphemeralKeys, "with-ephemeral-keys", 0, "@"},
{ aListKeys, "list-key", 0, "@" }, /* alias */
{ aListSigs, "list-sig", 0, "@" }, /* alias */
{ aListSigs, "check-sig",0, "@" }, /* alias */
{ oSkipVerify, "skip-verify",0, "@" },
{ oCompressKeys, "compress-keys",0, "@"},
{ oCompressSigs, "compress-sigs",0, "@"},
{ oAlwaysTrust, "always-trust", 0, "@"},
{ oNoVersion, "no-version", 0, "@"},
{ oLockOnce, "lock-once", 0, "@" },
{ oLockMultiple, "lock-multiple", 0, "@" },
{ oLockNever, "lock-never", 0, "@" },
{ oLoggerFD, "logger-fd",1, "@" },
{ oWithFingerprint, "with-fingerprint", 0, "@" },
{ oDisableCipherAlgo, "disable-cipher-algo", 2, "@" },
{ oDisablePubkeyAlgo, "disable-pubkey-algo", 2, "@" },
{ oHonorHttpProxy,"honor-http-proxy", 0, "@" },
{ oListOnly, "list-only", 0, "@"},
{ oIgnoreTimeConflict, "ignore-time-conflict", 0, "@" },
{ oNoRandomSeedFile, "no-random-seed-file", 0, "@" },
{0} };
int gpgsm_errors_seen = 0;
/* It is possible that we are currentlu running under setuid permissions */
static int maybe_setuid = 1;
/* Option --enable-special-filenames */
static int allow_special_filenames;
static char *build_list (const char *text,
const char *(*mapf)(int), int (*chkf)(int));
static void set_cmd (enum cmd_and_opt_values *ret_cmd,
enum cmd_and_opt_values new_cmd );
static void emergency_cleanup (void);
static int check_special_filename (const char *fname);
static int open_read (const char *filename);
static FILE *open_fwrite (const char *filename);
static void run_protect_tool (int argc, char **argv);
static int
our_pk_test_algo (int algo)
{
return 1;
}
static int
our_cipher_test_algo (int algo)
{
return 1;
}
static int
our_md_test_algo (int algo)
{
return 1;
}
static const char *
my_strusage( int level )
{
static char *digests, *pubkeys, *ciphers;
const char *p;
switch (level)
{
case 11: p = "gpgsm (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: gpgsm [options] [files] (-h for help)");
break;
case 41:
p = _("Syntax: gpgsm [options] [files]\n"
"sign, check, encrypt or decrypt using the S/MIME protocol\n"
"default operation depends on the input data\n");
break;
case 31: p = "\nHome: "; break;
case 32: p = opt.homedir; break;
case 33: p = _("\nSupported algorithms:\n"); break;
case 34:
if (!ciphers)
ciphers = build_list ("Cipher: ", gcry_cipher_algo_name,
our_cipher_test_algo );
p = ciphers;
break;
case 35:
if (!pubkeys)
pubkeys = build_list ("Pubkey: ", gcry_pk_algo_name,
our_pk_test_algo );
p = pubkeys;
break;
case 36:
if (!digests)
digests = build_list("Hash: ", gcry_md_algo_name, our_md_test_algo );
p = digests;
break;
default: p = NULL; break;
}
return p;
}
static char *
build_list (const char *text, const char * (*mapf)(int), int (*chkf)(int))
{
int i;
size_t n=strlen(text)+2;
char *list, *p;
if (maybe_setuid) {
gcry_control (GCRYCTL_DROP_PRIVS); /* drop setuid */
}
for (i=1; i < 110; i++ )
if (!chkf(i))
n += strlen(mapf(i)) + 2;
list = xmalloc (21 + n);
*list = 0;
for (p=NULL, i=1; i < 110; i++)
{
if (!chkf(i))
{
if( !p )
p = stpcpy (list, text );
else
p = stpcpy (p, ", ");
p = stpcpy (p, mapf(i) );
}
}
if (p)
p = stpcpy(p, "\n" );
return list;
}
static void
i18n_init(void)
{
#ifdef USE_SIMPLE_GETTEXT
set_gettext_file (PACKAGE_GT);
#else
# ifdef ENABLE_NLS
# ifdef HAVE_LC_MESSAGES
setlocale (LC_TIME, "");
setlocale (LC_MESSAGES, "");
# else
setlocale (LC_ALL, "" );
# endif
bindtextdomain (PACKAGE_GT, LOCALEDIR);
textdomain (PACKAGE_GT);
# endif
#endif
}
static void
wrong_args (const char *text)
{
fputs (_("usage: gpgsm [options] "), stderr);
fputs (text, stderr);
putc ('\n', stderr);
gpgsm_exit (2);
}
/* Setup the debugging. With a LEVEL of NULL only the active debug
flags are propagated to the subsystems. With LEVEL set, a specific
set of debug flags is set; thus overriding all flags already
set. */
static void
set_debug (const char *level)
{
if (!level)
;
else if (!strcmp (level, "none"))
opt.debug = 0;
else if (!strcmp (level, "basic"))
opt.debug = DBG_ASSUAN_VALUE;
else if (!strcmp (level, "advanced"))
opt.debug = DBG_ASSUAN_VALUE|DBG_X509_VALUE;
else if (!strcmp (level, "expert"))
opt.debug = (DBG_ASSUAN_VALUE|DBG_X509_VALUE
|DBG_CACHE_VALUE|DBG_CRYPTO_VALUE);
else if (!strcmp (level, "guru"))
opt.debug = ~0;
else
{
log_error (_("invalid debug-level `%s' given\n"), level);
gpgsm_exit(2);
}
if (opt.debug && !opt.verbose)
{
opt.verbose = 1;
gcry_control (GCRYCTL_SET_VERBOSITY, (int)opt.verbose);
}
if (opt.debug && opt.quiet)
opt.quiet = 0;
if (opt.debug & DBG_MPI_VALUE)
gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 2);
if (opt.debug & DBG_CRYPTO_VALUE )
gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 1);
}
static void
set_cmd (enum cmd_and_opt_values *ret_cmd, enum cmd_and_opt_values new_cmd)
{
enum cmd_and_opt_values cmd = *ret_cmd;
if (!cmd || cmd == new_cmd)
cmd = new_cmd;
else if ( cmd == aSign && new_cmd == aEncr )
cmd = aSignEncr;
else if ( cmd == aEncr && new_cmd == aSign )
cmd = aSignEncr;
else if ( (cmd == aSign && new_cmd == aClearsign)
|| (cmd == aClearsign && new_cmd == aSign) )
cmd = aClearsign;
else
{
log_error(_("conflicting commands\n"));
gpgsm_exit(2);
}
*ret_cmd = cmd;
}
/* Helper to add recipients to a list. */
static void
do_add_recipient (ctrl_t ctrl, const char *name,
certlist_t *recplist, int is_encrypt_to)
{
int rc = gpgsm_add_to_certlist (ctrl, name, 0, recplist, is_encrypt_to);
if (rc)
{
log_error (_("can't encrypt to `%s': %s\n"), name, gpg_strerror (rc));
gpgsm_status2 (ctrl, STATUS_INV_RECP,
gpg_err_code (rc) == -1? "1":
gpg_err_code (rc) == GPG_ERR_NO_PUBKEY? "1":
gpg_err_code (rc) == GPG_ERR_AMBIGUOUS_NAME? "2":
gpg_err_code (rc) == GPG_ERR_WRONG_KEY_USAGE? "3":
gpg_err_code (rc) == GPG_ERR_CERT_REVOKED? "4":
gpg_err_code (rc) == GPG_ERR_CERT_EXPIRED? "5":
gpg_err_code (rc) == GPG_ERR_NO_CRL_KNOWN? "6":
gpg_err_code (rc) == GPG_ERR_CRL_TOO_OLD? "7":
gpg_err_code (rc) == GPG_ERR_NO_POLICY_MATCH? "8":
"0",
name, NULL);
}
}
int
main ( int argc, char **argv)
{
ARGPARSE_ARGS pargs;
int orig_argc;
char **orig_argv;
const char *fname;
/* char *username;*/
int may_coredump;
STRLIST sl, remusr= NULL, locusr=NULL;
STRLIST nrings=NULL;
int detached_sig = 0;
FILE *configfp = NULL;
char *configname = NULL;
unsigned configlineno;
int parse_debug = 0;
int no_more_options = 0;
int default_config =1;
int default_keyring = 1;
char *logfile = NULL;
int greeting = 0;
int nogreeting = 0;
int debug_wait = 0;
const char *debug_level = NULL;
int use_random_seed = 1;
int with_fpr = 0;
char *def_digest_string = NULL;
enum cmd_and_opt_values cmd = 0;
struct server_control_s ctrl;
CERTLIST recplist = NULL;
CERTLIST signerlist = NULL;
int do_not_setup_keys = 0;
+
/* trap_unaligned ();*/
set_strusage (my_strusage);
gcry_control (GCRYCTL_SUSPEND_SECMEM_WARN);
/* We don't need any locking in libgcrypt unless we use any kind of
threading. */
gcry_control (GCRYCTL_DISABLE_INTERNAL_LOCKING);
/* Please note that we may running SUID(ROOT), so be very CAREFUL
when adding any stuff between here and the call to secmem_init()
somewhere after the option parsing */
log_set_prefix ("gpgsm", 1);
/* Try to auto set the character set. */
set_native_charset (NULL);
/* Check that the libraries are suitable. Do it here because the
option parse may need services of the library */
if (!gcry_check_version (NEED_LIBGCRYPT_VERSION) )
{
log_fatal( _("libgcrypt is too old (need %s, have %s)\n"),
NEED_LIBGCRYPT_VERSION, gcry_check_version (NULL) );
}
if (!ksba_check_version (NEED_KSBA_VERSION) )
{
log_fatal( _("libksba is too old (need %s, have %s)\n"),
NEED_KSBA_VERSION, ksba_check_version (NULL) );
}
gcry_control (GCRYCTL_USE_SECURE_RNDPOOL);
may_coredump = disable_core_dumps ();
gnupg_init_signals (0, emergency_cleanup);
create_dotlock (NULL); /* register locking cleanup */
i18n_init();
opt.def_cipher_algoid = "1.2.840.113549.3.7"; /*des-EDE3-CBC*/
#ifdef __MINGW32__
opt.homedir = read_w32_registry_string ( NULL,
"Software\\GNU\\GnuPG", "HomeDir" );
#else
opt.homedir = getenv ("GNUPGHOME");
#endif
if (!opt.homedir || !*opt.homedir )
opt.homedir = GNUPG_DEFAULT_HOMEDIR;
/* first check whether we have a config file on the commandline */
orig_argc = argc;
orig_argv = argv;
pargs.argc = &argc;
pargs.argv = &argv;
pargs.flags= 1|(1<<6); /* do not remove the args, ignore version */
while (arg_parse( &pargs, opts))
{
if (pargs.r_opt == oDebug || pargs.r_opt == oDebugAll)
parse_debug++;
else if (pargs.r_opt == oOptions)
{ /* yes there is one, so we do not try the default one but
read the config file when it is encountered at the
commandline */
default_config = 0;
}
else if (pargs.r_opt == oNoOptions)
default_config = 0; /* --no-options */
else if (pargs.r_opt == oHomedir)
opt.homedir = pargs.r.ret_str;
else if (pargs.r_opt == aCallProtectTool)
break; /* This break makes sure that --version and --help are
passed to the protect-tool. */
}
/* initialize the secure memory. */
gcry_control (GCRYCTL_INIT_SECMEM, 16384, 0);
maybe_setuid = 0;
/*
Now we are now working under our real uid
*/
ksba_set_malloc_hooks (gcry_malloc, gcry_realloc, gcry_free );
assuan_set_malloc_hooks (gcry_malloc, gcry_realloc, gcry_free);
assuan_set_assuan_log_stream (log_get_stream ());
assuan_set_assuan_log_prefix (log_get_prefix (NULL));
keybox_set_malloc_hooks (gcry_malloc, gcry_realloc, gcry_free);
/* Setup a default control structure for command line mode */
memset (&ctrl, 0, sizeof ctrl);
gpgsm_init_default_ctrl (&ctrl);
ctrl.no_server = 1;
ctrl.status_fd = -1; /* not status output */
ctrl.autodetect_encoding = 1;
- /* set the default option file */
+ /* Set the default option file */
if (default_config )
configname = make_filename (opt.homedir, "gpgsm.conf", NULL);
- /* cet the default policy file */
+ /* Set the default policy file */
opt.policy_file = make_filename (opt.homedir, "policies.txt", NULL);
argc = orig_argc;
argv = orig_argv;
pargs.argc = &argc;
pargs.argv = &argv;
pargs.flags = 1; /* do not remove the args */
next_pass:
if (configname) {
configlineno = 0;
configfp = fopen (configname, "r");
if (!configfp)
{
if (default_config)
{
if (parse_debug)
log_info (_("NOTE: no default option file `%s'\n"), configname);
}
else
{
log_error (_("option file `%s': %s\n"), configname, strerror(errno));
gpgsm_exit(2);
}
xfree(configname);
configname = NULL;
}
if (parse_debug && configname)
log_info (_("reading options from `%s'\n"), configname);
default_config = 0;
}
while (!no_more_options
&& optfile_parse (configfp, configname, &configlineno, &pargs, opts))
{
switch (pargs.r_opt)
{
case aGPGConfList:
set_cmd (&cmd, pargs.r_opt);
do_not_setup_keys = 1;
nogreeting = 1;
break;
case aServer:
opt.batch = 1;
set_cmd (&cmd, aServer);
break;
case aCallDirmngr:
opt.batch = 1;
set_cmd (&cmd, aCallDirmngr);
do_not_setup_keys = 1;
break;
case aCallProtectTool:
opt.batch = 1;
set_cmd (&cmd, aCallProtectTool);
no_more_options = 1; /* Stop parsing. */
do_not_setup_keys = 1;
break;
case aDeleteKey:
set_cmd (&cmd, aDeleteKey);
/*greeting=1;*/
do_not_setup_keys = 1;
break;
case aDetachedSign:
detached_sig = 1;
set_cmd (&cmd, aSign );
break;
case aKeygen:
set_cmd (&cmd, aKeygen);
greeting=1;
do_not_setup_keys = 1;
break;
case aCheckKeys:
case aImport:
case aSendKeys:
case aRecvKeys:
case aExport:
case aExportSecretKeyP12:
case aDumpKeys:
case aDumpExternalKeys:
case aDumpSecretKeys:
case aListKeys:
case aListExternalKeys:
case aListSecretKeys:
case aListSigs:
case aLearnCard:
case aPasswd:
case aKeydbClearSomeCertFlags:
do_not_setup_keys = 1;
set_cmd (&cmd, pargs.r_opt);
break;
case aSym:
case aDecrypt:
case aEncr:
case aSign:
case aClearsign:
case aVerify:
set_cmd (&cmd, pargs.r_opt);
break;
/* output encoding selection */
case oArmor:
ctrl.create_pem = 1;
break;
case oBase64:
ctrl.create_pem = 0;
ctrl.create_base64 = 1;
break;
case oNoArmor:
ctrl.create_pem = 0;
ctrl.create_base64 = 0;
break;
/* Input encoding selection */
case oAssumeArmor:
ctrl.autodetect_encoding = 0;
ctrl.is_pem = 1;
ctrl.is_base64 = 0;
break;
case oAssumeBase64:
ctrl.autodetect_encoding = 0;
ctrl.is_pem = 0;
ctrl.is_base64 = 1;
break;
case oAssumeBinary:
ctrl.autodetect_encoding = 0;
ctrl.is_pem = 0;
ctrl.is_base64 = 0;
break;
case oDisableCRLChecks:
opt.no_crl_check = 1;
break;
case oEnableCRLChecks:
opt.no_crl_check = 0;
break;
case oForceCRLRefresh:
opt.force_crl_refresh = 1;
break;
case oDisableOCSP:
ctrl.use_ocsp = opt.enable_ocsp = 0;
break;
case oEnableOCSP:
ctrl.use_ocsp = opt.enable_ocsp = 1;
break;
case oIncludeCerts: ctrl.include_certs = pargs.r.ret_int; break;
case oPolicyFile:
xfree (opt.policy_file);
if (*pargs.r.ret_str)
opt.policy_file = xstrdup (pargs.r.ret_str);
else
opt.policy_file = NULL;
break;
case oDisablePolicyChecks:
opt.no_policy_check = 1;
break;
case oEnablePolicyChecks:
opt.no_policy_check = 0;
break;
case oAutoIssuerKeyRetrieve:
opt.auto_issuer_key_retrieve = 1;
break;
case oOutput: opt.outfile = pargs.r.ret_str; break;
case oQuiet: opt.quiet = 1; break;
case oNoTTY: /* fixme:tty_no_terminal(1);*/ break;
case oDryRun: opt.dry_run = 1; break;
case oVerbose:
opt.verbose++;
gcry_control (GCRYCTL_SET_VERBOSITY, (int)opt.verbose);
break;
case oNoVerbose:
opt.verbose = 0;
gcry_control (GCRYCTL_SET_VERBOSITY, (int)opt.verbose);
break;
case oLogFile: logfile = pargs.r.ret_str; break;
case oBatch:
opt.batch = 1;
greeting = 0;
break;
case oNoBatch: opt.batch = 0; break;
case oAnswerYes: opt.answer_yes = 1; break;
case oAnswerNo: opt.answer_no = 1; break;
case oKeyring: append_to_strlist (&nrings, pargs.r.ret_str); break;
case oDebug: opt.debug |= pargs.r.ret_ulong; break;
case oDebugAll: opt.debug = ~0; break;
case oDebugLevel: debug_level = pargs.r.ret_str; break;
case oDebugWait: debug_wait = pargs.r.ret_int; break;
case oDebugAllowCoreDump:
may_coredump = enable_core_dumps ();
break;
case oDebugNoChainValidation: opt.no_chain_validation = 1; break;
case oDebugIgnoreExpiration: opt.ignore_expiration = 1; break;
+ case oFixedPassphrase: opt.fixed_passphrase = pargs.r.ret_str; break;
case oStatusFD: ctrl.status_fd = pargs.r.ret_int; break;
case oLoggerFD: log_set_fd (pargs.r.ret_int ); break;
case oWithMD5Fingerprint:
opt.with_md5_fingerprint=1; /*fall thru*/
case oWithFingerprint:
with_fpr=1; /*fall thru*/
case oFingerprint:
opt.fingerprint++;
break;
case oOptions:
/* config files may not be nested (silently ignore them) */
if (!configfp)
{
xfree(configname);
configname = xstrdup (pargs.r.ret_str);
goto next_pass;
}
break;
case oNoOptions: break; /* no-options */
case oHomedir: opt.homedir = pargs.r.ret_str; break;
case oAgentProgram: opt.agent_program = pargs.r.ret_str; break;
case oDisplay: opt.display = xstrdup (pargs.r.ret_str); break;
case oTTYname: opt.ttyname = xstrdup (pargs.r.ret_str); break;
case oTTYtype: opt.ttytype = xstrdup (pargs.r.ret_str); break;
case oLCctype: opt.lc_ctype = xstrdup (pargs.r.ret_str); break;
case oLCmessages: opt.lc_messages = xstrdup (pargs.r.ret_str); break;
case oDirmngrProgram: opt.dirmngr_program = pargs.r.ret_str; break;
case oProtectToolProgram:
opt.protect_tool_program = pargs.r.ret_str;
break;
case oFakedSystemTime:
gnupg_set_time ( (time_t)pargs.r.ret_ulong, 0);
break;
case oNoDefKeyring: default_keyring = 0; break;
case oNoGreeting: nogreeting = 1; break;
case oDefaultKey:
/* fixme:opt.def_secret_key = pargs.r.ret_str;*/
break;
case oDefRecipient:
if (*pargs.r.ret_str)
opt.def_recipient = xstrdup (pargs.r.ret_str);
break;
case oDefRecipientSelf:
xfree (opt.def_recipient);
opt.def_recipient = NULL;
opt.def_recipient_self = 1;
break;
case oNoDefRecipient:
xfree (opt.def_recipient);
opt.def_recipient = NULL;
opt.def_recipient_self = 0;
break;
case oWithKeyData: opt.with_key_data=1; /* fall thru */
case oWithColons: ctrl.with_colons = 1; break;
case oWithValidation: ctrl.with_validation=1; break;
case oWithEphemeralKeys: opt.with_ephemeral_keys=1; break;
case oSkipVerify: opt.skip_verify=1; break;
case oNoEncryptTo: opt.no_encrypt_to = 1; break;
case oEncryptTo: /* Store the recipient in the second list */
sl = add_to_strlist (&remusr, pargs.r.ret_str);
sl->flags = 1;
break;
case oRecipient: /* store the recipient */
add_to_strlist ( &remusr, pargs.r.ret_str);
break;
case oTextmodeShort: /*fixme:opt.textmode = 2;*/ break;
case oTextmode: /*fixme:opt.textmode=1;*/ break;
case oUser: /* store the local users, the first one is the default */
if (!opt.local_user)
opt.local_user = pargs.r.ret_str;
add_to_strlist (&locusr, pargs.r.ret_str);
break;
case oNoSecmemWarn:
gcry_control (GCRYCTL_DISABLE_SECMEM_WARN);
break;
case oCipherAlgo:
opt.def_cipher_algoid = pargs.r.ret_str;
break;
case oDisableCipherAlgo:
{
int algo = gcry_cipher_map_name (pargs.r.ret_str);
gcry_cipher_ctl (NULL, GCRYCTL_DISABLE_ALGO, &algo, sizeof algo);
}
break;
case oDisablePubkeyAlgo:
{
int algo = gcry_pk_map_name (pargs.r.ret_str);
gcry_pk_ctl (GCRYCTL_DISABLE_ALGO,&algo, sizeof algo );
}
break;
case oIgnoreTimeConflict: opt.ignore_time_conflict = 1; break;
case oNoRandomSeedFile: use_random_seed = 0; break;
case oEnableSpecialFilenames: allow_special_filenames =1; break;
case aDummy:
break;
default:
pargs.err = configfp? 1:2;
break;
}
}
if (configfp)
{
fclose (configfp);
configfp = NULL;
/* Keep a copy of the config filename. */
opt.config_filename = configname;
configname = NULL;
goto next_pass;
}
xfree (configname);
configname = NULL;
if (!opt.config_filename)
opt.config_filename = make_filename (opt.homedir, "gpgsm.conf", NULL);
if (log_get_errorcount(0))
gpgsm_exit(2);
if (nogreeting)
greeting = 0;
if (greeting)
{
fprintf(stderr, "%s %s; %s\n",
strusage(11), strusage(13), strusage(14) );
fprintf(stderr, "%s\n", strusage(15) );
}
# ifdef IS_DEVELOPMENT_VERSION
if (!opt.batch)
{
log_info ("NOTE: THIS IS A DEVELOPMENT VERSION!\n");
log_info ("It is only intended for test purposes and should NOT be\n");
log_info ("used in a production environment or with production keys!\n");
}
# endif
if (may_coredump && !opt.quiet)
log_info (_("WARNING: program may create a core file!\n"));
if (logfile && cmd == aServer)
{
log_set_file (logfile);
log_set_prefix (NULL, 1|2|4);
}
if (gnupg_faked_time_p ())
{
gnupg_isotime_t tbuf;
log_info (_("WARNING: running with faked system time: "));
gnupg_get_isotime (tbuf);
gpgsm_dump_time (tbuf);
log_printf ("\n");
}
/*FIXME if (opt.batch) */
/* tty_batchmode (1); */
gcry_control (GCRYCTL_RESUME_SECMEM_WARN);
set_debug (debug_level);
/* Although we alwasy use gpgsm_exit, we better install a regualr
exit handler so that at least the secure memory gets wiped
out. */
if (atexit (emergency_cleanup))
{
log_error ("atexit failed\n");
gpgsm_exit (2);
}
/* Must do this after dropping setuid, because the mapping functions
may try to load an module and we may have disabled an algorithm. */
if ( !gcry_cipher_map_name (opt.def_cipher_algoid)
|| !gcry_cipher_mode_from_oid (opt.def_cipher_algoid))
log_error (_("selected cipher algorithm is invalid\n"));
if (def_digest_string)
{
opt.def_digest_algo = gcry_md_map_name (def_digest_string);
xfree (def_digest_string);
def_digest_string = NULL;
if (our_md_test_algo(opt.def_digest_algo) )
log_error (_("selected digest algorithm is invalid\n"));
}
if (log_get_errorcount(0))
gpgsm_exit(2);
/* Set the random seed file. */
if (use_random_seed) {
char *p = make_filename (opt.homedir, "random_seed", NULL);
gcry_control (GCRYCTL_SET_RANDOM_SEED_FILE, p);
xfree(p);
}
if (!cmd && opt.fingerprint && !with_fpr)
set_cmd (&cmd, aListKeys);
if (!nrings && default_keyring) /* add default keybox */
keydb_add_resource ("pubring.kbx", 0, 0);
for (sl = nrings; sl; sl = sl->next)
keydb_add_resource (sl->d, 0, 0);
FREE_STRLIST(nrings);
if (!do_not_setup_keys)
{
for (sl = locusr; sl ; sl = sl->next)
{
int rc = gpgsm_add_to_certlist (&ctrl, sl->d, 1, &signerlist, 0);
if (rc)
{
log_error (_("can't sign using `%s': %s\n"),
sl->d, gpg_strerror (rc));
gpgsm_status2 (&ctrl, STATUS_INV_RECP,
gpg_err_code (rc) == -1? "1":
gpg_err_code (rc) == GPG_ERR_NO_PUBKEY? "1":
gpg_err_code (rc) == GPG_ERR_AMBIGUOUS_NAME? "2":
gpg_err_code (rc) == GPG_ERR_WRONG_KEY_USAGE? "3":
gpg_err_code (rc) == GPG_ERR_CERT_REVOKED? "4":
gpg_err_code (rc) == GPG_ERR_CERT_EXPIRED? "5":
gpg_err_code (rc) == GPG_ERR_NO_CRL_KNOWN? "6":
gpg_err_code (rc) == GPG_ERR_CRL_TOO_OLD? "7":
gpg_err_code (rc) == GPG_ERR_NO_POLICY_MATCH? "8":
gpg_err_code (rc) == GPG_ERR_NO_SECKEY? "9":
"0",
sl->d, NULL);
}
}
/* Build the recipient list. We first add the regular ones and then
the encrypt-to ones because the underlying function will silenty
ignore duplicates and we can't allow to keep a duplicate which is
flagged as encrypt-to as the actually encrypt function would then
complain about no (regular) recipients. */
for (sl = remusr; sl; sl = sl->next)
if (!(sl->flags & 1))
do_add_recipient (&ctrl, sl->d, &recplist, 0);
if (!opt.no_encrypt_to)
{
for (sl = remusr; sl; sl = sl->next)
if ((sl->flags & 1))
do_add_recipient (&ctrl, sl->d, &recplist, 1);
}
}
if (log_get_errorcount(0))
gpgsm_exit(1); /* must stop for invalid recipients */
fname = argc? *argv : NULL;
switch (cmd)
{
case aGPGConfList:
{ /* List options and default values in the GPG Conf format. */
/* The following list is taken from gnupg/tools/gpgconf-comp.c. */
/* Option flags. YOU MUST NOT CHANGE THE NUMBERS OF THE EXISTING
FLAGS, AS THEY ARE PART OF THE EXTERNAL INTERFACE. */
#define GC_OPT_FLAG_NONE 0UL
/* The RUNTIME flag for an option indicates that the option can be
changed at runtime. */
#define GC_OPT_FLAG_RUNTIME (1UL << 3)
/* The DEFAULT flag for an option indicates that the option has a
default value. */
#define GC_OPT_FLAG_DEFAULT (1UL << 4)
/* The DEF_DESC flag for an option indicates that the option has a
default, which is described by the value of the default field. */
#define GC_OPT_FLAG_DEF_DESC (1UL << 5)
/* The NO_ARG_DESC flag for an option indicates that the argument has
a default, which is described by the value of the ARGDEF field. */
#define GC_OPT_FLAG_NO_ARG_DESC (1UL << 6)
printf ("gpgconf-gpgsm.conf:%lu:\"%s\n",
GC_OPT_FLAG_DEFAULT, opt.config_filename);
printf ("verbose:%lu:\n"
"quiet:%lu:\n"
"debug-level:%lu:\"none:\n"
"log-file:%lu:\n",
GC_OPT_FLAG_NONE,
GC_OPT_FLAG_NONE,
GC_OPT_FLAG_DEFAULT,
GC_OPT_FLAG_NONE );
printf ("disable-crl-checks:%lu:\n",
GC_OPT_FLAG_NONE );
printf ("enable-ocsp:%lu:\n",
GC_OPT_FLAG_NONE );
printf ("include-certs:%lu:1:\n",
GC_OPT_FLAG_DEFAULT );
printf ("disable-policy-checks:%lu:\n",
GC_OPT_FLAG_NONE );
printf ("auto-issuer-key-retrieve:%lu:\n",
GC_OPT_FLAG_NONE );
}
break;
case aServer:
if (debug_wait)
{
log_debug ("waiting for debugger - my pid is %u .....\n",
(unsigned int)getpid());
sleep (debug_wait);
log_debug ("... okay\n");
}
gpgsm_server (recplist);
break;
case aCallDirmngr:
if (!argc)
wrong_args ("--call-dirmngr <command> {args}");
else
if (gpgsm_dirmngr_run_command (&ctrl, *argv, argc-1, argv+1))
gpgsm_exit (1);
break;
case aCallProtectTool:
run_protect_tool (argc, argv);
break;
case aEncr: /* encrypt the given file */
if (!argc)
gpgsm_encrypt (&ctrl, recplist, 0, stdout); /* from stdin */
else if (argc == 1)
gpgsm_encrypt (&ctrl, recplist, open_read (*argv), stdout); /* from file */
else
wrong_args ("--encrypt [datafile]");
break;
case aSign: /* sign the given file */
/* FIXME: We don't handle --output yet. We should also allow
to concatenate multiple files for signing because that is
what gpg does.*/
if (!argc)
gpgsm_sign (&ctrl, signerlist,
0, detached_sig, stdout); /* create from stdin */
else if (argc == 1)
gpgsm_sign (&ctrl, signerlist,
open_read (*argv), detached_sig, stdout); /* from file */
else
wrong_args ("--sign [datafile]");
break;
case aSignEncr: /* sign and encrypt the given file */
log_error ("this command has not yet been implemented\n");
break;
case aClearsign: /* make a clearsig */
log_error ("this command has not yet been implemented\n");
break;
case aVerify:
{
FILE *fp = NULL;
if (argc == 2 && opt.outfile)
log_info ("option --output ignored for a detached signature\n");
else if (opt.outfile)
fp = open_fwrite (opt.outfile);
if (!argc)
gpgsm_verify (&ctrl, 0, -1, fp); /* normal signature from stdin */
else if (argc == 1)
gpgsm_verify (&ctrl, open_read (*argv), -1, fp); /* std signature */
else if (argc == 2) /* detached signature (sig, detached) */
gpgsm_verify (&ctrl, open_read (*argv), open_read (argv[1]), NULL);
else
wrong_args ("--verify [signature [detached_data]]");
if (fp && fp != stdout)
fclose (fp);
}
break;
case aVerifyFiles:
log_error (_("this command has not yet been implemented\n"));
break;
case aDecrypt:
if (!argc)
gpgsm_decrypt (&ctrl, 0, stdout); /* from stdin */
else if (argc == 1)
gpgsm_decrypt (&ctrl, open_read (*argv), stdout); /* from file */
else
wrong_args ("--decrypt [filename]");
break;
case aDeleteKey:
for (sl=NULL; argc; argc--, argv++)
add_to_strlist (&sl, *argv);
gpgsm_delete (&ctrl, sl);
free_strlist(sl);
break;
case aListSigs:
ctrl.with_chain = 1;
case aListKeys:
for (sl=NULL; argc; argc--, argv++)
add_to_strlist (&sl, *argv);
gpgsm_list_keys (&ctrl, sl, stdout, (0 | (1<<6)));
free_strlist(sl);
break;
case aDumpKeys:
for (sl=NULL; argc; argc--, argv++)
add_to_strlist (&sl, *argv);
gpgsm_list_keys (&ctrl, sl, stdout, (256 | (1<<6)));
free_strlist(sl);
break;
case aListExternalKeys:
for (sl=NULL; argc; argc--, argv++)
add_to_strlist (&sl, *argv);
gpgsm_list_keys (&ctrl, sl, stdout,
(0 | (1<<7)));
free_strlist(sl);
break;
case aDumpExternalKeys:
for (sl=NULL; argc; argc--, argv++)
add_to_strlist (&sl, *argv);
gpgsm_list_keys (&ctrl, sl, stdout,
(256 | (1<<7)));
free_strlist(sl);
break;
case aListSecretKeys:
for (sl=NULL; argc; argc--, argv++)
add_to_strlist (&sl, *argv);
gpgsm_list_keys (&ctrl, sl, stdout, (2 | (1<<6)));
free_strlist(sl);
break;
case aDumpSecretKeys:
for (sl=NULL; argc; argc--, argv++)
add_to_strlist (&sl, *argv);
gpgsm_list_keys (&ctrl, sl, stdout, (256 | 2 | (1<<6)));
free_strlist(sl);
break;
case aKeygen: /* generate a key */
log_error ("this function is not yet available from the commandline\n");
break;
case aImport:
gpgsm_import_files (&ctrl, argc, argv, open_read);
break;
case aExport:
for (sl=NULL; argc; argc--, argv++)
add_to_strlist (&sl, *argv);
gpgsm_export (&ctrl, sl, stdout);
free_strlist(sl);
break;
case aExportSecretKeyP12:
if (argc == 1)
gpgsm_p12_export (&ctrl, *argv, stdout);
else
wrong_args ("--export-secret-key-p12 KEY-ID");
break;
case aSendKeys:
case aRecvKeys:
log_error ("this command has not yet been implemented\n");
break;
case aLearnCard:
if (argc)
wrong_args ("--learn-card");
else
{
int rc = gpgsm_agent_learn (&ctrl);
if (rc)
log_error ("error learning card: %s\n", gpg_strerror (rc));
}
break;
case aPasswd:
if (argc != 1)
wrong_args ("--passwd <key-Id>");
else
{
int rc;
ksba_cert_t cert = NULL;
char *grip = NULL;
rc = gpgsm_find_cert (*argv, &cert);
if (rc)
;
else if (!(grip = gpgsm_get_keygrip_hexstring (cert)))
rc = gpg_error (GPG_ERR_BUG);
else
{
char *desc = gpgsm_format_keydesc (cert);
rc = gpgsm_agent_passwd (&ctrl, grip, desc);
xfree (desc);
}
if (rc)
log_error ("error changing passphrase: %s\n", gpg_strerror (rc));
xfree (grip);
ksba_cert_release (cert);
}
break;
case aKeydbClearSomeCertFlags:
for (sl=NULL; argc; argc--, argv++)
add_to_strlist (&sl, *argv);
keydb_clear_some_cert_flags (&ctrl, sl);
free_strlist(sl);
break;
default:
log_error ("invalid command (there is no implicit command)\n");
break;
}
/* cleanup */
gpgsm_release_certlist (recplist);
gpgsm_release_certlist (signerlist);
FREE_STRLIST(remusr);
FREE_STRLIST(locusr);
gpgsm_exit(0);
return 8; /*NEVER REACHED*/
}
/* Note: This function is used by signal handlers!. */
static void
emergency_cleanup (void)
{
gcry_control (GCRYCTL_TERM_SECMEM );
}
void
gpgsm_exit (int rc)
{
gcry_control (GCRYCTL_UPDATE_RANDOM_SEED_FILE);
if (opt.debug & DBG_MEMSTAT_VALUE)
{
gcry_control( GCRYCTL_DUMP_MEMORY_STATS );
gcry_control( GCRYCTL_DUMP_RANDOM_STATS );
}
if (opt.debug)
gcry_control (GCRYCTL_DUMP_SECMEM_STATS );
emergency_cleanup ();
rc = rc? rc : log_get_errorcount(0)? 2 : gpgsm_errors_seen? 1 : 0;
exit (rc);
}
void
gpgsm_init_default_ctrl (struct server_control_s *ctrl)
{
ctrl->include_certs = 1; /* only include the signer's cert */
ctrl->use_ocsp = opt.enable_ocsp;
}
/* Check whether the filename has the form "-&nnnn", where n is a
non-zero number. Returns this number or -1 if it is not the case. */
static int
check_special_filename (const char *fname)
{
if (allow_special_filenames
&& fname && *fname == '-' && fname[1] == '&' ) {
int i;
fname += 2;
for (i=0; isdigit (fname[i]); i++ )
;
if ( !fname[i] )
return atoi (fname);
}
return -1;
}
/* Open the FILENAME for read and return the filedescriptor. Stop
with an error message in case of problems. "-" denotes stdin and
if special filenames are allowed the given fd is opened instead. */
static int
open_read (const char *filename)
{
int fd;
if (filename[0] == '-' && !filename[1])
return 0; /* stdin */
fd = check_special_filename (filename);
if (fd != -1)
return fd;
fd = open (filename, O_RDONLY);
if (fd == -1)
{
log_error (_("can't open `%s': %s\n"), filename, strerror (errno));
gpgsm_exit (2);
}
return fd;
}
/* Open FILENAME for fwrite and return the stream. Stop with an error
message in case of problems. "-" denotes stdout and if special
filenames are allowed the given fd is opened instead. Caller must
close the returned stream unless it is stdout. */
static FILE *
open_fwrite (const char *filename)
{
int fd;
FILE *fp;
if (filename[0] == '-' && !filename[1])
return stdout;
fd = check_special_filename (filename);
if (fd != -1)
{
fp = fdopen (dup (fd), "wb");
if (!fp)
{
log_error ("fdopen(%d) failed: %s\n", fd, strerror (errno));
gpgsm_exit (2);
}
return fp;
}
fp = fopen (filename, "wb");
if (!fp)
{
log_error (_("can't open `%s': %s\n"), filename, strerror (errno));
gpgsm_exit (2);
}
return fp;
}
static void
run_protect_tool (int argc, char **argv)
{
const char *pgm;
char **av;
int i;
if (!opt.protect_tool_program || !*opt.protect_tool_program)
pgm = GNUPG_DEFAULT_PROTECT_TOOL;
else
pgm = opt.protect_tool_program;
av = xcalloc (argc+2, sizeof *av);
av[0] = strrchr (pgm, '/');
if (!av[0])
av[0] = xstrdup (pgm);
for (i=1; argc; i++, argc--, argv++)
av[i] = *argv;
av[i] = NULL;
execv (pgm, av);
log_error ("error executing `%s': %s\n", pgm, strerror (errno));
gpgsm_exit (2);
}
diff --git a/sm/gpgsm.h b/sm/gpgsm.h
index a1813462f..20a3c5ee9 100644
--- a/sm/gpgsm.h
+++ b/sm/gpgsm.h
@@ -1,314 +1,315 @@
/* gpgsm.h - Global definitions for GpgSM
* Copyright (C) 2001, 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifndef GPGSM_H
#define GPGSM_H
#ifdef GPG_ERR_SOURCE_DEFAULT
#error GPG_ERR_SOURCE_DEFAULT already defined
#endif
#define GPG_ERR_SOURCE_DEFAULT GPG_ERR_SOURCE_GPGSM
#include <gpg-error.h>
#include <ksba.h>
#include "../common/util.h"
#include "../common/errors.h"
#define OUT_OF_CORE(a) (gpg_error (gpg_err_code_from_errno ((a))))
#define MAX_DIGEST_LEN 24
/* A large struct named "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 batch; /* run in batch mode, i.e w/o any user interaction */
int answer_yes; /* assume yes on most questions */
int answer_no; /* assume no on most questions */
int dry_run; /* don't change any persistent data */
const char *homedir; /* Configuration directory name */
const char *config_filename; /* Name of the used config file. */
const char *agent_program;
char *display;
char *ttyname;
char *ttytype;
char *lc_ctype;
char *lc_messages;
const char *dirmngr_program;
const char *protect_tool_program;
char *outfile; /* name of output file */
int with_key_data;/* include raw key in the column delimted output */
int fingerprint; /* list fingerprints in all key listings */
int with_md5_fingerprint; /* Also print an MD5 fingerprint for
standard key listings. */
int with_ephemeral_keys; /* Include ephemeral flagged keys in the
keylisting. */
int armor; /* force base64 armoring (see also ctrl.with_base64) */
int no_armor; /* don't try to figure out whether data is base64 armored*/
const char *def_cipher_algoid; /* cipher algorithm to use if
nothing else is specified */
int def_digest_algo; /* Ditto for hash algorithm */
int def_compress_algo; /* Ditto for compress algorithm */
char *def_recipient; /* userID of the default recipient */
int def_recipient_self; /* The default recipient is the default key */
int no_encrypt_to; /* Ignore all as encrypt to marked recipients. */
char *local_user; /* NULL or argument to -u */
int always_trust; /* Trust the given keys even if there is no
valid certification chain */
int skip_verify; /* do not check signatures on data */
int lock_once; /* Keep lock once they are set */
int ignore_time_conflict; /* Ignore certain time conflicts */
int no_crl_check; /* Don't do a CRL check */
int force_crl_refresh; /* Force refreshing the CRL. */
int enable_ocsp; /* Default to use OCSP checks. */
char *policy_file; /* full pathname of policy file */
int no_policy_check; /* ignore certificate policies */
int no_chain_validation; /* Bypass all cert chain validity tests */
int ignore_expiration; /* Ignore the notAfter validity checks. */
+ char *fixed_passphrase; /* Passphrase used by regression tests. */
int auto_issuer_key_retrieve; /* try to retrieve a missing issuer key. */
} opt;
#define DBG_X509_VALUE 1 /* debug x.509 data reading/writing */
#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 /* debug assuan communication */
#define DBG_X509 (opt.debug & DBG_X509_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;
/* Note that the default values for this are set by
gpgsm_init_default_ctrl() */
struct server_control_s {
int no_server; /* We are not running under server control */
int status_fd; /* Only for non-server mode */
struct server_local_s *server_local;
int with_colons; /* Use column delimited output format */
int with_chain; /* Include the certifying certs in a listing */
int with_validation;/* Validate each key while listing. */
int autodetect_encoding; /* Try to detect the input encoding */
int is_pem; /* Is in PEM format */
int is_base64; /* is in plain base-64 format */
int create_base64; /* Create base64 encoded output */
int create_pem; /* create PEM output */
const char *pem_name; /* PEM name to use */
int include_certs; /* -1 to send all certificates in the chain
along with a signature or the number of
certificates up the chain (0 = none, 1 = only
signer) */
int use_ocsp; /* Set to true if OCSP should be used. */
};
typedef struct server_control_s *CTRL;
typedef struct server_control_s *ctrl_t;
/* data structure used in base64.c */
typedef struct base64_context_s *Base64Context;
struct certlist_s {
struct certlist_s *next;
ksba_cert_t cert;
int is_encrypt_to; /* True if the certificate has been set through
the --encrypto-to option. */
};
typedef struct certlist_s *CERTLIST;
typedef struct certlist_s *certlist_t;
/*-- gpgsm.c --*/
void gpgsm_exit (int rc);
void gpgsm_init_default_ctrl (struct server_control_s *ctrl);
/*-- server.c --*/
void gpgsm_server (certlist_t default_recplist);
void gpgsm_status (ctrl_t ctrl, int no, const char *text);
void gpgsm_status2 (ctrl_t ctrl, int no, ...);
void gpgsm_status_with_err_code (ctrl_t ctrl, int no, const char *text,
gpg_err_code_t ec);
/*-- fingerprint --*/
char *gpgsm_get_fingerprint (ksba_cert_t cert, int algo,
char *array, int *r_len);
char *gpgsm_get_fingerprint_string (ksba_cert_t cert, int algo);
char *gpgsm_get_fingerprint_hexstring (ksba_cert_t cert, int algo);
unsigned long gpgsm_get_short_fingerprint (ksba_cert_t cert);
char *gpgsm_get_keygrip (ksba_cert_t cert, char *array);
char *gpgsm_get_keygrip_hexstring (ksba_cert_t cert);
int gpgsm_get_key_algo_info (ksba_cert_t cert, unsigned int *nbits);
char *gpgsm_get_certid (ksba_cert_t cert);
/*-- base64.c --*/
int gpgsm_create_reader (Base64Context *ctx,
ctrl_t ctrl, FILE *fp, int allow_multi_pem,
ksba_reader_t *r_reader);
int gpgsm_reader_eof_seen (Base64Context ctx);
void gpgsm_destroy_reader (Base64Context ctx);
int gpgsm_create_writer (Base64Context *ctx,
ctrl_t ctrl, FILE *fp, ksba_writer_t *r_writer);
int gpgsm_finish_writer (Base64Context ctx);
void gpgsm_destroy_writer (Base64Context ctx);
/*-- certdump.c --*/
void gpgsm_print_serial (FILE *fp, ksba_const_sexp_t p);
void gpgsm_print_time (FILE *fp, ksba_isotime_t t);
void gpgsm_print_name (FILE *fp, const char *string);
void gpgsm_dump_cert (const char *text, ksba_cert_t cert);
void gpgsm_dump_serial (ksba_const_sexp_t p);
void gpgsm_dump_time (ksba_isotime_t t);
void gpgsm_dump_string (const char *string);
char *gpgsm_format_serial (ksba_const_sexp_t p);
char *gpgsm_format_name (const char *name);
char *gpgsm_format_keydesc (ksba_cert_t cert);
/*-- certcheck.c --*/
int gpgsm_check_cert_sig (ksba_cert_t issuer_cert, ksba_cert_t cert);
int gpgsm_check_cms_signature (ksba_cert_t cert, ksba_const_sexp_t sigval,
gcry_md_hd_t md, int hash_algo);
/* fixme: move create functions to another file */
int gpgsm_create_cms_signature (ctrl_t ctrl,
ksba_cert_t cert, gcry_md_hd_t md, int mdalgo,
char **r_sigval);
/*-- certchain.c --*/
int gpgsm_walk_cert_chain (ksba_cert_t start, ksba_cert_t *r_next);
int gpgsm_is_root_cert (ksba_cert_t cert);
int gpgsm_validate_chain (ctrl_t ctrl, ksba_cert_t cert,
ksba_isotime_t r_exptime,
int listmode, FILE *listfp,
unsigned int flags);
int gpgsm_basic_cert_check (ksba_cert_t cert);
/*-- certlist.c --*/
int gpgsm_cert_use_sign_p (ksba_cert_t cert);
int gpgsm_cert_use_encrypt_p (ksba_cert_t cert);
int gpgsm_cert_use_verify_p (ksba_cert_t cert);
int gpgsm_cert_use_decrypt_p (ksba_cert_t cert);
int gpgsm_cert_use_cert_p (ksba_cert_t cert);
int gpgsm_add_cert_to_certlist (ctrl_t ctrl, ksba_cert_t cert,
certlist_t *listaddr, int is_encrypt_to);
int gpgsm_add_to_certlist (ctrl_t ctrl, const char *name, int secret,
certlist_t *listaddr, int is_encrypt_to);
void gpgsm_release_certlist (certlist_t list);
int gpgsm_find_cert (const char *name, ksba_cert_t *r_cert);
/*-- keylist.c --*/
gpg_error_t gpgsm_list_keys (ctrl_t ctrl, STRLIST names,
FILE *fp, unsigned int mode);
/*-- import.c --*/
int gpgsm_import (ctrl_t ctrl, int in_fd);
int gpgsm_import_files (ctrl_t ctrl, int nfiles, char **files,
int (*of)(const char *fname));
/*-- export.c --*/
void gpgsm_export (ctrl_t ctrl, STRLIST names, FILE *fp);
void gpgsm_p12_export (ctrl_t ctrl, const char *name, FILE *fp);
/*-- delete.c --*/
int gpgsm_delete (ctrl_t ctrl, STRLIST names);
/*-- verify.c --*/
int gpgsm_verify (ctrl_t ctrl, int in_fd, int data_fd, FILE *out_fp);
/*-- sign.c --*/
int gpgsm_get_default_cert (ctrl_t ctrl, ksba_cert_t *r_cert);
int gpgsm_sign (ctrl_t ctrl, CERTLIST signerlist,
int data_fd, int detached, FILE *out_fp);
/*-- encrypt.c --*/
int gpgsm_encrypt (ctrl_t ctrl, CERTLIST recplist, int in_fd, FILE *out_fp);
/*-- decrypt.c --*/
int gpgsm_decrypt (ctrl_t ctrl, int in_fd, FILE *out_fp);
/*-- certreqgen.c --*/
int gpgsm_genkey (ctrl_t ctrl, int in_fd, FILE *out_fp);
/*-- call-agent.c --*/
int gpgsm_agent_pksign (ctrl_t ctrl, const char *keygrip, const char *desc,
unsigned char *digest,
size_t digestlen,
int digestalgo,
char **r_buf, size_t *r_buflen);
int gpgsm_agent_pkdecrypt (ctrl_t ctrl, const char *keygrip, const char *desc,
ksba_const_sexp_t ciphertext,
char **r_buf, size_t *r_buflen);
int gpgsm_agent_genkey (ctrl_t ctrl,
ksba_const_sexp_t keyparms, ksba_sexp_t *r_pubkey);
int gpgsm_agent_istrusted (ctrl_t ctrl, ksba_cert_t cert);
int gpgsm_agent_havekey (ctrl_t ctrl, const char *hexkeygrip);
int gpgsm_agent_marktrusted (ctrl_t ctrl, ksba_cert_t cert);
int gpgsm_agent_learn (ctrl_t ctrl);
int gpgsm_agent_passwd (ctrl_t ctrl, const char *hexkeygrip, const char *desc);
/*-- call-dirmngr.c --*/
int gpgsm_dirmngr_isvalid (ctrl_t ctrl,
ksba_cert_t cert, ksba_cert_t issuer_cert,
int use_ocsp);
int gpgsm_dirmngr_lookup (ctrl_t ctrl, STRLIST names,
void (*cb)(void*, ksba_cert_t), void *cb_value);
int gpgsm_dirmngr_run_command (ctrl_t ctrl, const char *command,
int argc, char **argv);
/*-- misc.c --*/
void setup_pinentry_env (void);
#endif /*GPGSM_H*/
diff --git a/sm/import.c b/sm/import.c
index c5581eb64..5d3484d92 100644
--- a/sm/import.c
+++ b/sm/import.c
@@ -1,725 +1,742 @@
/* import.c - Import certificates
* Copyright (C) 2001, 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#include <config.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <time.h>
#include <assert.h>
#include <signal.h>
#include <fcntl.h>
#include <sys/wait.h>
#include "gpgsm.h"
#include <gcrypt.h>
#include <ksba.h>
#include "keydb.h"
#include "i18n.h"
#ifdef _POSIX_OPEN_MAX
#define MAX_OPEN_FDS _POSIX_OPEN_MAX
#else
#define MAX_OPEN_FDS 20
#endif
struct stats_s {
unsigned long count;
unsigned long imported;
unsigned long unchanged;
unsigned long not_imported;
unsigned long secret_read;
unsigned long secret_imported;
unsigned long secret_dups;
};
static gpg_error_t parse_p12 (ksba_reader_t reader, FILE **retfp,
struct stats_s *stats);
static void
print_imported_status (CTRL ctrl, ksba_cert_t cert, int new_cert)
{
char *fpr;
fpr = gpgsm_get_fingerprint_hexstring (cert, GCRY_MD_SHA1);
if (new_cert)
gpgsm_status2 (ctrl, STATUS_IMPORTED, fpr, "[X.509]", NULL);
gpgsm_status2 (ctrl, STATUS_IMPORT_OK,
new_cert? "1":"0", fpr, NULL);
xfree (fpr);
}
/* Print an IMPORT_PROBLEM status. REASON is one of:
0 := "No specific reason given".
1 := "Invalid Certificate".
2 := "Issuer Certificate missing".
3 := "Certificate Chain too long".
4 := "Error storing certificate".
*/
static void
print_import_problem (CTRL ctrl, ksba_cert_t cert, int reason)
{
char *fpr = NULL;
char buf[25];
int i;
sprintf (buf, "%d", reason);
if (cert)
{
fpr = gpgsm_get_fingerprint_hexstring (cert, GCRY_MD_SHA1);
/* detetect an error (all high) value */
for (i=0; fpr[i] == 'F'; i++)
;
if (!fpr[i])
{
xfree (fpr);
fpr = NULL;
}
}
gpgsm_status2 (ctrl, STATUS_IMPORT_PROBLEM, buf, fpr, NULL);
xfree (fpr);
}
void
print_imported_summary (CTRL ctrl, struct stats_s *stats)
{
char buf[14*25];
if (!opt.quiet)
{
log_info (_("total number processed: %lu\n"), stats->count);
if (stats->imported)
{
log_info (_(" imported: %lu"), stats->imported );
log_printf ("\n");
}
if (stats->unchanged)
log_info (_(" unchanged: %lu\n"), stats->unchanged);
if (stats->secret_read)
log_info (_(" secret keys read: %lu\n"), stats->secret_read );
if (stats->secret_imported)
log_info (_(" secret keys imported: %lu\n"), stats->secret_imported );
if (stats->secret_dups)
log_info (_(" secret keys unchanged: %lu\n"), stats->secret_dups );
if (stats->not_imported)
log_info (_(" not imported: %lu\n"), stats->not_imported);
}
sprintf(buf, "%lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu",
stats->count,
0l /*stats->no_user_id*/,
stats->imported,
0l /*stats->imported_rsa*/,
stats->unchanged,
0l /*stats->n_uids*/,
0l /*stats->n_subk*/,
0l /*stats->n_sigs*/,
0l /*stats->n_revoc*/,
stats->secret_read,
stats->secret_imported,
stats->secret_dups,
0l /*stats->skipped_new_keys*/,
stats->not_imported
);
gpgsm_status (ctrl, STATUS_IMPORT_RES, buf);
}
static void
check_and_store (CTRL ctrl, struct stats_s *stats, ksba_cert_t cert, int depth)
{
int rc;
if (stats)
stats->count++;
if ( depth >= 50 )
{
log_error (_("certificate chain too long\n"));
if (stats)
stats->not_imported++;
print_import_problem (ctrl, cert, 3);
return;
}
/* Some basic checks, but don't care about missing certificates;
this is so that we are able to import entire certificate chains
- w/o requirening a special order (i.e. root-CA first). This used
+ w/o requiring a special order (i.e. root-CA first). This used
to be different but because gpgsm_verify even imports
certificates without any checks, it doesn't matter much and the
code gets much cleaner. A housekeeping function to remove
- certificates w/o an anchor would be nice, though. */
+ certificates w/o an anchor would be nice, though.
+
+ Optionally we do a full validation in addition to the basic test.
+ */
rc = gpgsm_basic_cert_check (cert);
- if (!rc || gpg_err_code (rc) == GPG_ERR_MISSING_CERT)
+ if (!rc && ctrl->with_validation)
+ rc = gpgsm_validate_chain (ctrl, cert, NULL, 0, NULL, 0);
+ if (!rc || (!ctrl->with-validation
+ && gpg_err_code (rc) == GPG_ERR_MISSING_CERT) )
{
int existed;
if (!keydb_store_cert (cert, 0, &existed))
{
ksba_cert_t next = NULL;
if (!existed)
{
print_imported_status (ctrl, cert, 1);
if (stats)
stats->imported++;
}
else
{
print_imported_status (ctrl, cert, 0);
if (stats)
stats->unchanged++;
}
if (opt.verbose > 1 && existed)
{
if (depth)
log_info ("issuer certificate already in DB\n");
else
log_info ("certificate already in DB\n");
}
else if (opt.verbose && !existed)
{
if (depth)
log_info ("issuer certificate imported\n");
else
log_info ("certificate imported\n");
}
/* Now lets walk up the chain and import all certificates up
the chain. This is required in case we already stored
parent certificates in the ephemeral keybox. Do not
update the statistics, though. */
if (!gpgsm_walk_cert_chain (cert, &next))
{
check_and_store (ctrl, NULL, next, depth+1);
ksba_cert_release (next);
}
}
else
{
log_error (_("error storing certificate\n"));
if (stats)
stats->not_imported++;
print_import_problem (ctrl, cert, 4);
}
}
else
{
log_error (_("basic certificate checks failed - not imported\n"));
if (stats)
stats->not_imported++;
print_import_problem (ctrl, cert,
gpg_err_code (rc) == GPG_ERR_MISSING_CERT? 2 :
gpg_err_code (rc) == GPG_ERR_BAD_CERT? 1 : 0);
}
}
static int
import_one (CTRL ctrl, struct stats_s *stats, int in_fd)
{
int rc;
Base64Context b64reader = NULL;
ksba_reader_t reader;
ksba_cert_t cert = NULL;
ksba_cms_t cms = NULL;
FILE *fp = NULL;
ksba_content_type_t ct;
int any = 0;
fp = fdopen ( dup (in_fd), "rb");
if (!fp)
{
rc = gpg_error (gpg_err_code_from_errno (errno));
log_error ("fdopen() failed: %s\n", strerror (errno));
goto leave;
}
rc = gpgsm_create_reader (&b64reader, ctrl, fp, 1, &reader);
if (rc)
{
log_error ("can't create reader: %s\n", gpg_strerror (rc));
goto leave;
}
/* We need to loop here to handle multiple PEM objects in one
file. */
do
{
ksba_cms_release (cms); cms = NULL;
ksba_cert_release (cert); cert = NULL;
ct = ksba_cms_identify (reader);
if (ct == KSBA_CT_SIGNED_DATA)
{ /* This is probably a signed-only message - import the certs */
ksba_stop_reason_t stopreason;
int i;
rc = ksba_cms_new (&cms);
if (rc)
goto leave;
rc = ksba_cms_set_reader_writer (cms, reader, NULL);
if (rc)
{
log_error ("ksba_cms_set_reader_writer failed: %s\n",
gpg_strerror (rc));
goto leave;
}
do
{
rc = ksba_cms_parse (cms, &stopreason);
if (rc)
{
log_error ("ksba_cms_parse failed: %s\n", gpg_strerror (rc));
goto leave;
}
if (stopreason == KSBA_SR_BEGIN_DATA)
log_info ("not a certs-only message\n");
}
while (stopreason != KSBA_SR_READY);
for (i=0; (cert=ksba_cms_get_cert (cms, i)); i++)
{
check_and_store (ctrl, stats, cert, 0);
ksba_cert_release (cert);
cert = NULL;
}
if (!i)
log_error ("no certificate found\n");
else
any = 1;
}
else if (ct == KSBA_CT_PKCS12)
{ /* This seems to be a pkcs12 message. We use an external
tool to parse the message and to store the private keys.
We need to use a another reader here to parse the
certificate we included in the p12 file; then we continue
to look for other pkcs12 files (works only if they are in
PEM format. */
FILE *certfp;
Base64Context b64p12rdr;
ksba_reader_t p12rdr;
rc = parse_p12 (reader, &certfp, stats);
if (!rc)
{
any = 1;
rewind (certfp);
rc = gpgsm_create_reader (&b64p12rdr, ctrl, certfp, 1, &p12rdr);
if (rc)
{
log_error ("can't create reader: %s\n", gpg_strerror (rc));
fclose (certfp);
goto leave;
}
do
{
ksba_cert_release (cert); cert = NULL;
rc = ksba_cert_new (&cert);
if (!rc)
{
rc = ksba_cert_read_der (cert, p12rdr);
if (!rc)
check_and_store (ctrl, stats, cert, 0);
}
ksba_reader_clear (p12rdr, NULL, NULL);
}
while (!rc && !gpgsm_reader_eof_seen (b64p12rdr));
if (gpg_err_code (rc) == GPG_ERR_EOF)
rc = 0;
gpgsm_destroy_reader (b64p12rdr);
fclose (certfp);
if (rc)
goto leave;
}
}
else if (ct == KSBA_CT_NONE)
{ /* Failed to identify this message - assume a certificate */
rc = ksba_cert_new (&cert);
if (rc)
goto leave;
rc = ksba_cert_read_der (cert, reader);
if (rc)
goto leave;
check_and_store (ctrl, stats, cert, 0);
any = 1;
}
else
{
log_error ("can't extract certificates from input\n");
rc = gpg_error (GPG_ERR_NO_DATA);
}
ksba_reader_clear (reader, NULL, NULL);
}
while (!gpgsm_reader_eof_seen (b64reader));
leave:
if (any && gpg_err_code (rc) == GPG_ERR_EOF)
rc = 0;
ksba_cms_release (cms);
ksba_cert_release (cert);
gpgsm_destroy_reader (b64reader);
if (fp)
fclose (fp);
return rc;
}
int
gpgsm_import (CTRL ctrl, int in_fd)
{
int rc;
struct stats_s stats;
memset (&stats, 0, sizeof stats);
rc = import_one (ctrl, &stats, in_fd);
print_imported_summary (ctrl, &stats);
/* If we never printed an error message do it now so that a command
line invocation will return with an error (log_error keeps a
global errorcount) */
if (rc && !log_get_errorcount (0))
log_error (_("error importing certificate: %s\n"), gpg_strerror (rc));
return rc;
}
int
gpgsm_import_files (CTRL ctrl, int nfiles, char **files,
int (*of)(const char *fname))
{
int rc = 0;
struct stats_s stats;
memset (&stats, 0, sizeof stats);
if (!nfiles)
rc = import_one (ctrl, &stats, 0);
else
{
for (; nfiles && !rc ; nfiles--, files++)
{
int fd = of (*files);
rc = import_one (ctrl, &stats, fd);
close (fd);
if (rc == -1)
rc = 0;
}
}
print_imported_summary (ctrl, &stats);
/* If we never printed an error message do it now so that a command
line invocation will return with an error (log_error keeps a
global errorcount) */
if (rc && !log_get_errorcount (0))
log_error (_("error importing certificate: %s\n"), gpg_strerror (rc));
return rc;
}
/* Fork and exec the protecttool, connect the file descriptor of
INFILE to stdin, return a new stream in STATUSFILE, write the
output to OUTFILE and the pid of the process in PID. Returns 0 on
success or an error code. */
static gpg_error_t
popen_protect_tool (const char *pgmname,
FILE *infile, FILE *outfile, FILE **statusfile, pid_t *pid)
{
gpg_error_t err;
int fd, fdout, rp[2];
int n, i;
fflush (infile);
rewind (infile);
fd = fileno (infile);
fdout = fileno (outfile);
if (fd == -1 || fdout == -1)
log_fatal ("no file descriptor for temporary file: %s\n",
strerror (errno));
/* Now start the protect-tool. */
if (pipe (rp) == -1)
{
err = gpg_error_from_errno (errno);
log_error (_("error creating a pipe: %s\n"), strerror (errno));
return err;
}
*pid = fork ();
if (*pid == -1)
{
err = gpg_error_from_errno (errno);
log_error (_("error forking process: %s\n"), strerror (errno));
close (rp[0]);
close (rp[1]);
return err;
}
if (!*pid)
{ /* Child. */
const char *arg0;
arg0 = strrchr (pgmname, '/');
if (arg0)
arg0++;
else
arg0 = pgmname;
/* Connect the infile to stdin. */
if (fd != 0 && dup2 (fd, 0) == -1)
log_fatal ("dup2 stdin failed: %s\n", strerror (errno));
/* Connect the outfile to stdout. */
if (fdout != 1 && dup2 (fdout, 1) == -1)
log_fatal ("dup2 stdout failed: %s\n", strerror (errno));
/* Connect stderr to our pipe. */
if (rp[1] != 2 && dup2 (rp[1], 2) == -1)
log_fatal ("dup2 stderr failed: %s\n", strerror (errno));
/* Close all other files. */
n = sysconf (_SC_OPEN_MAX);
if (n < 0)
n = MAX_OPEN_FDS;
for (i=3; i < n; i++)
close(i);
errno = 0;
setup_pinentry_env ();
- execlp (pgmname, arg0,
- "--homedir", opt.homedir,
- "--p12-import",
- "--store",
- "--no-fail-on-exist",
- "--enable-status-msg",
- "--",
- NULL);
+ if (opt.fixed_passphrase)
+ execlp (pgmname, arg0,
+ "--homedir", opt.homedir,
+ "--p12-import",
+ "--store",
+ "--no-fail-on-exist",
+ "--enable-status-msg",
+ "--passphrase", opt.fixed_passphrase,
+ "--",
+ NULL);
+ else
+ execlp (pgmname, arg0,
+ "--homedir", opt.homedir,
+ "--p12-import",
+ "--store",
+ "--no-fail-on-exist",
+ "--enable-status-msg",
+ "--",
+ NULL);
/* No way to print anything, as we have closed all streams. */
_exit (31);
}
/* Parent. */
close (rp[1]);
*statusfile = fdopen (rp[0], "r");
if (!*statusfile)
{
err = gpg_error_from_errno (errno);
log_error ("can't fdopen pipe for reading: %s", strerror (errno));
kill (*pid, SIGTERM);
return err;
}
return 0;
}
/* Assume that the reader is at a pkcs#12 message and try to import
certificates from that stupid format. We will alos store secret
keys. All of the pkcs#12 parsing and key storing is handled by the
gpg-protect-tool, we merely have to take care of receiving the
certificates. On success RETFP returns a temporary file with
certificates. */
static gpg_error_t
parse_p12 (ksba_reader_t reader, FILE **retfp, struct stats_s *stats)
{
const char *pgmname;
gpg_error_t err = 0, child_err = 0;
int i, c, cont_line;
unsigned int pos;
FILE *tmpfp, *certfp = NULL, *fp = NULL;
char buffer[1024];
size_t nread;
pid_t pid = -1;
if (!opt.protect_tool_program || !*opt.protect_tool_program)
pgmname = GNUPG_DEFAULT_PROTECT_TOOL;
else
pgmname = opt.protect_tool_program;
*retfp = NULL;
/* To avoid an extra feeder process or doing selects and because
gpg-protect-tool will anyway parse the entire pkcs#12 message in
memory, we simply use tempfiles here and pass them to
the gpg-protect-tool. */
tmpfp = tmpfile ();
if (!tmpfp)
{
err = gpg_error_from_errno (errno);
log_error (_("error creating temporary file: %s\n"), strerror (errno));
goto cleanup;
}
while (!(err = ksba_reader_read (reader, buffer, sizeof buffer, &nread)))
{
if (nread && fwrite (buffer, nread, 1, tmpfp) != 1)
{
err = gpg_error_from_errno (errno);
log_error (_("error writing to temporary file: %s\n"),
strerror (errno));
goto cleanup;
}
}
if (gpg_err_code (err) == GPG_ERR_EOF)
err = 0;
if (err)
{
log_error (_("error reading input: %s\n"), gpg_strerror (err));
goto cleanup;
}
certfp = tmpfile ();
if (!certfp)
{
err = gpg_error_from_errno (errno);
log_error (_("error creating temporary file: %s\n"), strerror (errno));
goto cleanup;
}
err = popen_protect_tool (pgmname, tmpfp, certfp, &fp, &pid);
if (err)
{
pid = -1;
goto cleanup;
}
fclose (tmpfp);
tmpfp = NULL;
/* Read stderr of the protect tool. */
pos = 0;
cont_line = 0;
while ((c=getc (fp)) != EOF)
{
/* fixme: We could here grep for status information of the
protect tool to figure out better error codes for
CHILD_ERR. */
buffer[pos++] = c;
if (pos >= sizeof buffer - 5 || c == '\n')
{
buffer[pos - (c == '\n')] = 0;
if (cont_line)
log_printf ("%s", buffer);
else
{
if (!strncmp (buffer, "gpg-protect-tool: [PROTECT-TOOL:] ",34))
{
char *p, *pend;
p = buffer + 34;
pend = strchr (p, ' ');
if (pend)
*pend = 0;
if ( !strcmp (p, "secretkey-stored"))
{
stats->count++;
stats->secret_read++;
stats->secret_imported++;
}
else if ( !strcmp (p, "secretkey-exists"))
{
stats->count++;
stats->secret_read++;
stats->secret_dups++;
}
else if ( !strcmp (p, "bad-passphrase"))
;
}
else
log_info ("%s", buffer);
}
pos = 0;
cont_line = (c != '\n');
}
}
if (pos)
{
buffer[pos] = 0;
if (cont_line)
log_printf ("%s\n", buffer);
else
log_info ("%s\n", buffer);
}
/* If we found no error in the output of the cild, setup a suitable
error code, which will later be reset if the exit status of the
child is 0. */
if (!child_err)
child_err = gpg_error (GPG_ERR_DECRYPT_FAILED);
cleanup:
if (tmpfp)
fclose (tmpfp);
if (fp)
fclose (fp);
if (pid != -1)
{
int status;
while ( (i=waitpid (pid, &status, 0)) == -1 && errno == EINTR)
;
if (i == -1)
log_error (_("waiting for protect-tool to terminate failed: %s\n"),
strerror (errno));
else if (WIFEXITED (status) && WEXITSTATUS (status) == 31)
log_error (_("error running `%s': probably not installed\n"), pgmname);
else if (WIFEXITED (status) && WEXITSTATUS (status))
log_error (_("error running `%s': exit status %d\n"), pgmname,
WEXITSTATUS (status));
else if (!WIFEXITED (status))
log_error (_("error running `%s': terminated\n"), pgmname);
else
child_err = 0;
}
if (!err)
err = child_err;
if (err)
{
if (certfp)
fclose (certfp);
}
else
*retfp = certfp;
return err;
}
diff --git a/tests/ChangeLog b/tests/ChangeLog
index 68f9b4e21..c012c2346 100644
--- a/tests/ChangeLog
+++ b/tests/ChangeLog
@@ -1,73 +1,77 @@
+2004-08-16 Werner Koch <wk@g10code.de>
+
+ * Makefile.am: Descend into the new pkits directory
+
2004-02-20 Werner Koch <wk@gnupg.org>
* Makefile.am: Reset GPG_AGENT_INFO here
* runtest: and not anymore here.
2002-12-04 Werner Koch <wk@gnupg.org>
* inittests (gpgsm.conf): Fake system time.
2002-10-31 Neal H. Walfield <neal@g10code.de>
* Makefile.am (inittests.stamp): Do not set LD_LIBRARY_PATH here.
(TESTS_ENVIRONMENT): Do it here. And also frob $(LIBGCRYPT_LIBS)
and $(PTH_LIBS).
2002-10-31 Neal H. Walfield <neal@g10code.de>
* asschk.c (die): New macro.
(read_assuan): If in verbose mode, dump the string that was read.
(write_assuan): Be more verbose on failure.
2002-09-04 Neal H. Walfield <neal@g10code.de>
* Makefile.am (inittests.stamp): Do not set LD_LIBRARY_PATH, but
rather prepend it. Be more robust and prefer printf over echo -n.
2002-09-04 Marcus Brinkmann <marcus@g10code.de>
* asschk.c (start_server): Close the parent's file descriptors in
the child.
(read_assuan): Variable NREAD removed. Cut off the received line
currectly if more than one line was read.
2002-09-03 Neal H. Walfield <neal@g10code.de>
* Makefile.am (inittests.stamp): Construct an LD_LIBRARY_PATH from
LDFLAGS.
2002-08-09 Werner Koch <wk@gnupg.org>
* asschk.c (cmd_getenv): New.
(expand_line): Allow / as variable name delimiter.
* sm-sign+verify, sm-verify: Use $srcdir so that a VPATH build works.
* Makefile.am: Fixes for make dist.
* samplekets/Makefile.am: New.
2002-08-08 Werner Koch <wk@gnupg.org>
* asschk.c: Added some new features.
* runtest, inittests: New.
* text-1.txt, text-2.txt, text-3.txt: New.
* text-1.osig.pem, text-1.dsig.pem, text-1.osig-bad.pem: New.
* text-2.osig.pem, text-2.osig-bad.pem: New.
* samplekeys : New directory
* sm-verify, sm-sign+verify: The first test scripts.
2002-08-06 Werner Koch <wk@gnupg.org>
* Makefile.am, asschk.c: New.
Copyright 2002 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.
diff --git a/tests/pkits/ChangeLog b/tests/pkits/ChangeLog
new file mode 100644
index 000000000..2f0b7ba0e
--- /dev/null
+++ b/tests/pkits/ChangeLog
@@ -0,0 +1,18 @@
+2004-08-16 Werner Koch <wk@g10code.de>
+
+ Started implementing PKITS based tests.
+
+
+ Copyright 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.
+
+
+
+
diff --git a/tests/pkits/Makefile.am b/tests/pkits/Makefile.am
new file mode 100644
index 000000000..41fdec497
--- /dev/null
+++ b/tests/pkits/Makefile.am
@@ -0,0 +1,69 @@
+# Makefile.am - tests using NIST's PKITS
+# 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+
+## Process this file with automake to produce Makefile.in
+
+GPGSM = ../../sm/gpgsm
+
+TESTS_ENVIRONMENT = GNUPGHOME=`pwd` GPG_AGENT_INFO= LC_ALL=C GPGSM=$(GPGSM) \
+ LD_LIBRARY_PATH=$$(seen=0; \
+ for i in $(LDFLAGS) $(LIBGCRYPT_LIBS) $(PTH_LIBS); \
+ do \
+ if echo "$$i" | egrep '^-L' >/dev/null 2>&1; \
+ then \
+ if test $$seen = 0; \
+ then \
+ seen=1; \
+ else \
+ printf ":"; \
+ fi; \
+ printf "%s" "$${i}" | sed 's/^-L//'; \
+ fi; \
+ done; \
+ if test $$seen != 0 \
+ && test x$${LD_LIBRARY_PATH} != x; \
+ then \
+ printf ":"; \
+ fi; \
+ printf "%s" "$${LD_LIBRARY_PATH}") $(srcdir)/runtest
+
+
+
+testscripts = import-all-certs validate-all-certs
+
+
+
+EXTRA_DIST = PKITS_data.tar.bz2 inittests runtest $(testscripts)
+ import-all-certs.data
+
+TESTS = $(testscripts)
+
+CLEANFILES = inittests.stamp x y y z out err *.lock .\#lk* *.log
+
+DISTCLEANFILES = pubring.kbx~ random_seed
+
+all-local: inittests.stamp
+
+clean-local:
+ srcdir=$(srcdir) $(TESTS_ENVIRONMENT) $(srcdir)/inittests --clean
+
+inittests.stamp: inittests
+ srcdir=$(srcdir) $(TESTS_ENVIRONMENT) $(srcdir)/inittests
+ echo timestamp >./inittests.stamp
+
diff --git a/tests/pkits/PKITS_data.tar.bz2 b/tests/pkits/PKITS_data.tar.bz2
new file mode 100644
index 000000000..0604f2286
Binary files /dev/null and b/tests/pkits/PKITS_data.tar.bz2 differ
diff --git a/tests/pkits/README b/tests/pkits/README
new file mode 100644
index 000000000..a4290fe1f
--- /dev/null
+++ b/tests/pkits/README
@@ -0,0 +1,9 @@
+tests/pkits/README
+
+These are tests based on NIST's Public Key Interoperability Test Suite
+(PKITS) as downloaded on 2004-08-16 from
+http://csrc.nist.gov/pki/testing/x509paths.html .
+
+README - this file.
+PKITS_data.tar.bz2 - the orginal ZIP file, repackaged as a tarball.
+Makefile.am - Part of our build system.
diff --git a/tests/pkits/common.sh b/tests/pkits/common.sh
new file mode 100644
index 000000000..5e773ea5d
--- /dev/null
+++ b/tests/pkits/common.sh
@@ -0,0 +1,135 @@
+#!/bin/sh
+# common.sh - common defs for all tests -*- sh -*-
+# 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+
+# reset some environment variables because we do not want to test locals
+export LANG=C
+export LANGUAGE=C
+export LC_ALL=C
+
+
+[ "$VERBOSE" = yes ] && set -x
+[ -z "$srcdir" ] && srcdir="."
+[ -z "$top_srcdir" ] && top_srcdir=".."
+[ -z "$GPGSM" ] && GPGSM="../../sm/gpgsm"
+
+
+if [ "$GNUPGHOME" != "`pwd`" ]; then
+ echo "inittests: please set GNUPGHOME to the tests/pkits directory" >&2
+ exit 1
+fi
+
+if [ -n "$GPG_AGENT_INFO" ]; then
+ echo "inittests: please unset GPG_AGENT_INFO" >&2
+ exit 1
+fi
+
+
+
+#--------------------------------
+#------ utility functions -------
+#--------------------------------
+
+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"
+}
+
+fatal () {
+ echo "$pgmname: fatal:" $* >&2
+ exit 1;
+}
+
+error () {
+ echo "$pgmname:" $* >&2
+ exit 1
+}
+
+info () {
+ echo "$pgmname:" $* >&2
+}
+
+info_n () {
+ $echo_n "$pgmname:" $* >&2
+}
+
+pass () {
+ echo "PASS: " $* >&2
+ pass_count=`expr ${pass_count} + 1`
+}
+
+fail () {
+ echo "FAIL: " $* >&2
+ fail_count=`expr ${fail_count} + 1`
+}
+
+unresolved () {
+ echo "UNRESOLVED: " $* >&2
+ unresolved_count=`expr ${unresolved_count} + 1`
+}
+
+unsupported () {
+ echo "UNSUPPORTED: " $* >&2
+ unsupported_count=`expr ${unsupported_count} + 1`
+}
+
+
+final_result () {
+ [ $pass_count = 0 ] || info "$pass_count tests passed"
+ [ $fail_count = 0 ] || info "$fail_count tests failed"
+ [ $unresolved_count = 0 ] || info "$unresolved_count tests unresolved"
+ [ $unsupported_count = 0 ] || info "$unsupported_count tests unsupported"
+ if [ $fail_count = 0 ]; then
+ info "all tests passed"
+ else
+ exit 1
+ fi
+}
+
+set -e
+
+pgmname=`basename $0`
+
+pass_count=0
+fail_count=0
+unresolved_count=0
+unsupported_count=0
+
+
+#trap cleanup SIGHUP SIGINT SIGQUIT
+exec 2> ${pgmname}.log
+
+:
+# end
diff --git a/tests/pkits/import-all-certs b/tests/pkits/import-all-certs
new file mode 100755
index 000000000..d1af5fb03
--- /dev/null
+++ b/tests/pkits/import-all-certs
@@ -0,0 +1,53 @@
+#!/bin/sh
+# Copyright (C) 2004 Free Software Foundation, Inc. -*- sh -*-
+#
+# This file is part of GnuPG.
+#
+# GnuPG is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# GnuPG is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+
+. ${srcdir:-.}/common.sh || exit 2
+
+while read flag dummy name; do
+ case $flag in \#*) continue;; esac
+ [ -z "$flag" ] && continue;
+
+ if ${GPGSM} -q --import certs/$name ; then
+ if [ "$flag" = 'p' ]; then
+ pass "importing certificate \`$name' succeeded"
+ elif [ "$flag" = 'f' ]; then
+ fail "importing certificate \`$name' succeeded"
+ elif [ "$flag" = '?' ]; then
+ unresolved "importing certificate \`$name' succeeded"
+ elif [ "$flag" = 'u' ]; then
+ unsupported "importing certificate \`$name' succeeded"
+ else
+ info "importing certificate \`$name' succeeded - (flag=$flag)"
+ fi
+ else
+ if [ "$flag" = 'p' ]; then
+ fail "importing certificate \`$name' failed"
+ elif [ "$flag" = 'f' ]; then
+ pass "importing certificate \`$name' failed"
+ elif [ "$flag" = '?' ]; then
+ unresolved "importing certificate \`$name' failed"
+ elif [ "$flag" = 'u' ]; then
+ unsupported "importing certificate \`$name' failed"
+ else
+ info "importing certificate \`$name' failed - (flag=$flag)"
+ fi
+ fi
+done < $srcdir/import-all-certs.data
+
+final_result
diff --git a/tests/pkits/import-all-certs.data b/tests/pkits/import-all-certs.data
new file mode 100644
index 000000000..18708aa61
--- /dev/null
+++ b/tests/pkits/import-all-certs.data
@@ -0,0 +1,490 @@
+# The first column is for the basic import test, the second for a
+# validation test.
+
+# Make sure that the root certificate is imported first
+p p TrustAnchorRootCertificate.crt
+
+p p AllCertificatesNoPoliciesTest2EE.crt
+p p AllCertificatesSamePoliciesTest10EE.crt
+p p AllCertificatesSamePoliciesTest13EE.crt
+p p AllCertificatesanyPolicyTest11EE.crt
+p p AnyPolicyTest14EE.crt
+p p BadCRLIssuerNameCACert.crt
+p p BadCRLSignatureCACert.crt
+f f BadSignedCACert.crt
+p f BadnotAfterDateCACert.crt
+
+# UTC: "470101120100Z" i.e. not before 2047-01-01
+p f BadnotBeforeDateCACert.crt
+
+p p BasicSelfIssuedCRLSigningKeyCACert.crt
+
+# For yet unknown reasons gpgsm claims a bad signature.
+? ? BasicSelfIssuedCRLSigningKeyCRLCert.crt
+
+p p BasicSelfIssuedNewKeyCACert.crt
+
+# For yet unknown reasons gpgsm claims a bad signature.
+? ? BasicSelfIssuedNewKeyOldWithNewCACert.crt
+
+p p BasicSelfIssuedOldKeyCACert.crt
+
+# For yet unknown reasons gpgsm claims a bad signature.
+? ? BasicSelfIssuedOldKeyNewWithOldCACert.crt
+
+p p CPSPointerQualifierTest20EE.crt
+
+u u DSACACert.crt
+u u DSAParametersInheritedCACert.crt
+
+p p DifferentPoliciesTest12EE.crt
+p p DifferentPoliciesTest3EE.crt
+p p DifferentPoliciesTest4EE.crt
+p p DifferentPoliciesTest5EE.crt
+p p DifferentPoliciesTest7EE.crt
+p p DifferentPoliciesTest8EE.crt
+p p DifferentPoliciesTest9EE.crt
+p p GeneralizedTimeCRLnextUpdateCACert.crt
+p p GoodCACert.crt
+p p GoodsubCACert.crt
+
+# gpgsm: critical certificate extension 2.5.29.33 (policyMappings)
+# is not supported
+p u GoodsubCAPanyPolicyMapping1to2CACert.crt
+
+# fixme: gpgme does not fail for it.
+p f InvalidBadCRLIssuerNameTest5EE.crt
+
+p f InvalidBadCRLSignatureTest4EE.crt
+p f InvalidBasicSelfIssuedCRLSigningKeyTest7EE.crt
+
+f f InvalidBasicSelfIssuedCRLSigningKeyTest8EE.crt
+
+p f InvalidBasicSelfIssuedNewWithOldTest5EE.crt
+
+f f InvalidBasicSelfIssuedOldWithNewTest2EE.crt
+
+p f InvalidCASignatureTest2EE.crt
+
+p f InvalidCAnotAfterDateTest5EE.crt
+p f InvalidCAnotBeforeDateTest1EE.crt
+p f InvalidDNSnameConstraintsTest31EE.crt
+p f InvalidDNSnameConstraintsTest33EE.crt
+p f InvalidDNSnameConstraintsTest38EE.crt
+p f InvalidDNandRFC822nameConstraintsTest28EE.crt
+p f InvalidDNandRFC822nameConstraintsTest29EE.crt
+p f InvalidDNnameConstraintsTest10EE.crt
+p f InvalidDNnameConstraintsTest12EE.crt
+p f InvalidDNnameConstraintsTest13EE.crt
+p f InvalidDNnameConstraintsTest15EE.crt
+p f InvalidDNnameConstraintsTest16EE.crt
+p f InvalidDNnameConstraintsTest17EE.crt
+
+f f InvalidDNnameConstraintsTest20EE.crt
+
+p f InvalidDNnameConstraintsTest2EE.crt
+p f InvalidDNnameConstraintsTest3EE.crt
+p f InvalidDNnameConstraintsTest7EE.crt
+p f InvalidDNnameConstraintsTest8EE.crt
+p f InvalidDNnameConstraintsTest9EE.crt
+
+u u InvalidDSASignatureTest6EE.crt
+
+f f InvalidEESignatureTest3EE.crt
+
+p f InvalidEEnotAfterDateTest6EE.crt
+p f InvalidEEnotBeforeDateTest2EE.crt
+p f InvalidIDPwithindirectCRLTest23EE.crt
+p f InvalidIDPwithindirectCRLTest26EE.crt
+p f InvalidLongSerialNumberTest18EE.crt
+p f InvalidMappingFromanyPolicyTest7EE.crt
+p f InvalidMappingToanyPolicyTest8EE.crt
+p f InvalidMissingCRLTest1EE.crt
+p f InvalidMissingbasicConstraintsTest1EE.crt
+p f InvalidNameChainingOrderTest2EE.crt
+p f InvalidNameChainingTest1EE.crt
+p f InvalidNegativeSerialNumberTest15EE.crt
+p f InvalidOldCRLnextUpdateTest11EE.crt
+p f InvalidPolicyMappingTest10EE.crt
+p f InvalidPolicyMappingTest2EE.crt
+p f InvalidPolicyMappingTest4EE.crt
+p f InvalidRFC822nameConstraintsTest22EE.crt
+p f InvalidRFC822nameConstraintsTest24EE.crt
+p f InvalidRFC822nameConstraintsTest26EE.crt
+p f InvalidRevokedCATest2EE.crt
+p f InvalidRevokedEETest3EE.crt
+
+f f InvalidSelfIssuedinhibitAnyPolicyTest10EE.crt
+
+p f InvalidSelfIssuedinhibitAnyPolicyTest8EE.crt
+p f InvalidSelfIssuedinhibitPolicyMappingTest10EE.crt
+p f InvalidSelfIssuedinhibitPolicyMappingTest11EE.crt
+p f InvalidSelfIssuedinhibitPolicyMappingTest8EE.crt
+p f InvalidSelfIssuedinhibitPolicyMappingTest9EE.crt
+p f InvalidSelfIssuedpathLenConstraintTest16EE.crt
+p f InvalidSelfIssuedrequireExplicitPolicyTest7EE.crt
+p f InvalidSelfIssuedrequireExplicitPolicyTest8EE.crt
+
+f f InvalidSeparateCertificateandCRLKeysTest20EE.crt
+f f InvalidSeparateCertificateandCRLKeysTest21EE.crt
+
+p f InvalidURInameConstraintsTest35EE.crt
+p f InvalidURInameConstraintsTest37EE.crt
+p f InvalidUnknownCRLEntryExtensionTest8EE.crt
+p f InvalidUnknownCRLExtensionTest10EE.crt
+p f InvalidUnknownCRLExtensionTest9EE.crt
+p f InvalidUnknownCriticalCertificateExtensionTest2EE.crt
+p f InvalidWrongCRLTest6EE.crt
+p f InvalidcAFalseTest2EE.crt
+p f InvalidcAFalseTest3EE.crt
+p f InvalidcRLIssuerTest27EE.crt
+p f InvalidcRLIssuerTest31EE.crt
+p f InvalidcRLIssuerTest32EE.crt
+p f InvalidcRLIssuerTest34EE.crt
+p f InvalidcRLIssuerTest35EE.crt
+p f InvaliddeltaCRLIndicatorNoBaseTest1EE.crt
+p f InvaliddeltaCRLTest10EE.crt
+p f InvaliddeltaCRLTest3EE.crt
+p f InvaliddeltaCRLTest4EE.crt
+p f InvaliddeltaCRLTest6EE.crt
+p f InvaliddeltaCRLTest9EE.crt
+p f InvaliddistributionPointTest2EE.crt
+p f InvaliddistributionPointTest3EE.crt
+p f InvaliddistributionPointTest6EE.crt
+p f InvaliddistributionPointTest8EE.crt
+p f InvaliddistributionPointTest9EE.crt
+p f InvalidinhibitAnyPolicyTest1EE.crt
+p f InvalidinhibitAnyPolicyTest4EE.crt
+p f InvalidinhibitAnyPolicyTest5EE.crt
+p f InvalidinhibitAnyPolicyTest6EE.crt
+p f InvalidinhibitPolicyMappingTest1EE.crt
+p f InvalidinhibitPolicyMappingTest3EE.crt
+p f InvalidinhibitPolicyMappingTest5EE.crt
+p f InvalidinhibitPolicyMappingTest6EE.crt
+p f InvalidkeyUsageCriticalcRLSignFalseTest4EE.crt
+p f InvalidkeyUsageCriticalkeyCertSignFalseTest1EE.crt
+p f InvalidkeyUsageNotCriticalcRLSignFalseTest5EE.crt
+p f InvalidkeyUsageNotCriticalkeyCertSignFalseTest2EE.crt
+p f InvalidonlyContainsAttributeCertsTest14EE.crt
+p f InvalidonlyContainsCACertsTest12EE.crt
+p f InvalidonlyContainsUserCertsTest11EE.crt
+p f InvalidonlySomeReasonsTest15EE.crt
+p f InvalidonlySomeReasonsTest16EE.crt
+p f InvalidonlySomeReasonsTest17EE.crt
+p f InvalidonlySomeReasonsTest20EE.crt
+p f InvalidonlySomeReasonsTest21EE.crt
+p f InvalidpathLenConstraintTest10EE.crt
+p f InvalidpathLenConstraintTest11EE.crt
+p f InvalidpathLenConstraintTest12EE.crt
+p f InvalidpathLenConstraintTest5EE.crt
+p f InvalidpathLenConstraintTest6EE.crt
+p f InvalidpathLenConstraintTest9EE.crt
+p f Invalidpre2000CRLnextUpdateTest12EE.crt
+p f Invalidpre2000UTCEEnotAfterDateTest7EE.crt
+p f InvalidrequireExplicitPolicyTest3EE.crt
+p f InvalidrequireExplicitPolicyTest5EE.crt
+p p LongSerialNumberCACert.crt
+p p Mapping1to2CACert.crt
+p p MappingFromanyPolicyCACert.crt
+p p MappingToanyPolicyCACert.crt
+p p MissingbasicConstraintsCACert.crt
+p p NameOrderingCACert.crt
+p p NegativeSerialNumberCACert.crt
+p p NoCRLCACert.crt
+p p NoPoliciesCACert.crt
+p p NoissuingDistributionPointCACert.crt
+p p OldCRLnextUpdateCACert.crt
+p p OverlappingPoliciesTest6EE.crt
+p p P12Mapping1to3CACert.crt
+p p P12Mapping1to3subCACert.crt
+p p P12Mapping1to3subsubCACert.crt
+p p P1Mapping1to234CACert.crt
+p p P1Mapping1to234subCACert.crt
+p p P1anyPolicyMapping1to2CACert.crt
+p p PanyPolicyMapping1to2CACert.crt
+p p PoliciesP1234CACert.crt
+p p PoliciesP1234subCAP123Cert.crt
+p p PoliciesP1234subsubCAP123P12Cert.crt
+p p PoliciesP123CACert.crt
+p p PoliciesP123subCAP12Cert.crt
+p p PoliciesP123subsubCAP12P1Cert.crt
+p p PoliciesP123subsubCAP12P2Cert.crt
+p p PoliciesP123subsubsubCAP12P2P1Cert.crt
+p p PoliciesP12CACert.crt
+p p PoliciesP12subCAP1Cert.crt
+p p PoliciesP12subsubCAP1P2Cert.crt
+p p PoliciesP2subCA2Cert.crt
+p p PoliciesP2subCACert.crt
+p p PoliciesP3CACert.crt
+p p RFC3280MandatoryAttributeTypesCACert.crt
+p p RFC3280OptionalAttributeTypesCACert.crt
+p p RevokedsubCACert.crt
+p p RolloverfromPrintableStringtoUTF8StringCACert.crt
+p p SeparateCertificateandCRLKeysCA2CRLSigningCert.crt
+p p SeparateCertificateandCRLKeysCA2CertificateSigningCACert.crt
+p p SeparateCertificateandCRLKeysCRLSigningCert.crt
+p p SeparateCertificateandCRLKeysCertificateSigningCACert.crt
+p p TwoCRLsCACert.crt
+p p UIDCACert.crt
+p p UTF8StringCaseInsensitiveMatchCACert.crt
+p p UTF8StringEncodedNamesCACert.crt
+p p UnknownCRLEntryExtensionCACert.crt
+p p UnknownCRLExtensionCACert.crt
+p p UserNoticeQualifierTest15EE.crt
+p p UserNoticeQualifierTest16EE.crt
+p p UserNoticeQualifierTest17EE.crt
+p p UserNoticeQualifierTest18EE.crt
+p p UserNoticeQualifierTest19EE.crt
+p p ValidBasicSelfIssuedCRLSigningKeyTest6EE.crt
+
+# For yet unknown reasons gpgsm claims a bad signature.
+? ? ValidBasicSelfIssuedNewWithOldTest3EE.crt
+
+p p ValidBasicSelfIssuedNewWithOldTest4EE.crt
+
+# For yet unknown reasons gpgsm claims a bad signature.
+? ? ValidBasicSelfIssuedOldWithNewTest1EE.crt
+
+p p ValidCertificatePathTest1EE.crt
+p p ValidDNSnameConstraintsTest30EE.crt
+p p ValidDNSnameConstraintsTest32EE.crt
+p p ValidDNandRFC822nameConstraintsTest27EE.crt
+p p ValidDNnameConstraintsTest11EE.crt
+
+# This certificate has an empty subject sequence. Our parser does not
+# support this yet and it is unlikely that gpgsm will be able to cope
+# with it at all.
+u u ValidDNnameConstraintsTest14EE.crt
+
+p p ValidDNnameConstraintsTest18EE.crt
+
+# For yet unknown reasons gpgsm claims a bad signature.
+? ? ValidDNnameConstraintsTest19EE.crt
+
+p p ValidDNnameConstraintsTest1EE.crt
+p p ValidDNnameConstraintsTest4EE.crt
+p p ValidDNnameConstraintsTest5EE.crt
+p p ValidDNnameConstraintsTest6EE.crt
+
+u p ValidDSAParameterInheritanceTest5EE.crt
+u p ValidDSASignaturesTest4EE.crt
+
+p p ValidGeneralizedTimeCRLnextUpdateTest13EE.crt
+p p ValidGeneralizedTimenotAfterDateTest8EE.crt
+p p ValidGeneralizedTimenotBeforeDateTest4EE.crt
+p p ValidIDPwithindirectCRLTest22EE.crt
+p p ValidIDPwithindirectCRLTest24EE.crt
+p p ValidIDPwithindirectCRLTest25EE.crt
+p p ValidLongSerialNumberTest16EE.crt
+p p ValidLongSerialNumberTest17EE.crt
+p p ValidNameChainingCapitalizationTest5EE.crt
+p p ValidNameChainingWhitespaceTest3EE.crt
+p p ValidNameChainingWhitespaceTest4EE.crt
+p p ValidNameUIDsTest6EE.crt
+p p ValidNegativeSerialNumberTest14EE.crt
+p p ValidNoissuingDistributionPointTest10EE.crt
+p p ValidPolicyMappingTest11EE.crt
+p p ValidPolicyMappingTest12EE.crt
+p p ValidPolicyMappingTest13EE.crt
+p p ValidPolicyMappingTest14EE.crt
+p p ValidPolicyMappingTest1EE.crt
+p p ValidPolicyMappingTest3EE.crt
+p p ValidPolicyMappingTest5EE.crt
+p p ValidPolicyMappingTest6EE.crt
+p p ValidPolicyMappingTest9EE.crt
+p p ValidRFC3280MandatoryAttributeTypesTest7EE.crt
+p p ValidRFC3280OptionalAttributeTypesTest8EE.crt
+p p ValidRFC822nameConstraintsTest21EE.crt
+p p ValidRFC822nameConstraintsTest23EE.crt
+p p ValidRFC822nameConstraintsTest25EE.crt
+p p ValidRolloverfromPrintableStringtoUTF8StringTest10EE.crt
+p p ValidSelfIssuedinhibitAnyPolicyTest7EE.crt
+p p ValidSelfIssuedinhibitAnyPolicyTest9EE.crt
+p p ValidSelfIssuedinhibitPolicyMappingTest7EE.crt
+
+# For yet unknown reasons gpgsm claims a bad signature.
+? ? ValidSelfIssuedpathLenConstraintTest15EE.crt
+
+p p ValidSelfIssuedpathLenConstraintTest17EE.crt
+
+# For yet unknown reasons gpgsm claims a bad signature.
+? ? ValidSelfIssuedrequireExplicitPolicyTest6EE.crt
+
+# For yet unknown reasons gpgsm claims a bad signature.
+? ? ValidSeparateCertificateandCRLKeysTest19EE.crt
+
+p p ValidTwoCRLsTest7EE.crt
+p p ValidURInameConstraintsTest34EE.crt
+p p ValidURInameConstraintsTest36EE.crt
+p p ValidUTF8StringCaseInsensitiveMatchTest11EE.crt
+p p ValidUTF8StringEncodedNamesTest9EE.crt
+p p ValidUnknownNotCriticalCertificateExtensionTest1EE.crt
+p p ValidbasicConstraintsNotCriticalTest4EE.crt
+p p ValidcRLIssuerTest28EE.crt
+p p ValidcRLIssuerTest29EE.crt
+p p ValidcRLIssuerTest30EE.crt
+p p ValidcRLIssuerTest33EE.crt
+p p ValiddeltaCRLTest2EE.crt
+p p ValiddeltaCRLTest5EE.crt
+p p ValiddeltaCRLTest7EE.crt
+p p ValiddeltaCRLTest8EE.crt
+p p ValiddistributionPointTest1EE.crt
+p p ValiddistributionPointTest4EE.crt
+p p ValiddistributionPointTest5EE.crt
+p p ValiddistributionPointTest7EE.crt
+p p ValidinhibitAnyPolicyTest2EE.crt
+p p ValidinhibitPolicyMappingTest2EE.crt
+p p ValidinhibitPolicyMappingTest4EE.crt
+p p ValidkeyUsageNotCriticalTest3EE.crt
+p p ValidonlyContainsCACertsTest13EE.crt
+p p ValidonlySomeReasonsTest18EE.crt
+p p ValidonlySomeReasonsTest19EE.crt
+p p ValidpathLenConstraintTest13EE.crt
+p p ValidpathLenConstraintTest14EE.crt
+p p ValidpathLenConstraintTest7EE.crt
+p p ValidpathLenConstraintTest8EE.crt
+p p Validpre2000UTCnotBeforeDateTest3EE.crt
+p p ValidrequireExplicitPolicyTest1EE.crt
+p p ValidrequireExplicitPolicyTest2EE.crt
+p p ValidrequireExplicitPolicyTest4EE.crt
+p p WrongCRLCACert.crt
+p p anyPolicyCACert.crt
+p p basicConstraintsCriticalcAFalseCACert.crt
+p p basicConstraintsNotCriticalCACert.crt
+p p basicConstraintsNotCriticalcAFalseCACert.crt
+p p deltaCRLCA1Cert.crt
+p p deltaCRLCA2Cert.crt
+p p deltaCRLCA3Cert.crt
+p p deltaCRLIndicatorNoBaseCACert.crt
+p p distributionPoint1CACert.crt
+p p distributionPoint2CACert.crt
+p p indirectCRLCA1Cert.crt
+p p indirectCRLCA2Cert.crt
+p p indirectCRLCA3Cert.crt
+p p indirectCRLCA3cRLIssuerCert.crt
+p p indirectCRLCA4Cert.crt
+p p indirectCRLCA4cRLIssuerCert.crt
+p p indirectCRLCA5Cert.crt
+p p indirectCRLCA6Cert.crt
+p p inhibitAnyPolicy0CACert.crt
+p p inhibitAnyPolicy1CACert.crt
+
+# For yet unknown reasons gpgsm claims a bad signature.
+? ? inhibitAnyPolicy1SelfIssuedCACert.crt
+? ? inhibitAnyPolicy1SelfIssuedsubCA2Cert.crt
+
+p p inhibitAnyPolicy1subCA1Cert.crt
+
+# For yet unknown reasons gpgsm claims a bad signature.
+? ? inhibitAnyPolicy1subCA2Cert.crt
+
+p p inhibitAnyPolicy1subCAIAP5Cert.crt
+p p inhibitAnyPolicy1subsubCA2Cert.crt
+p p inhibitAnyPolicy5CACert.crt
+p p inhibitAnyPolicy5subCACert.crt
+p p inhibitAnyPolicy5subsubCACert.crt
+p p inhibitAnyPolicyTest3EE.crt
+p p inhibitPolicyMapping0CACert.crt
+p p inhibitPolicyMapping0subCACert.crt
+p p inhibitPolicyMapping1P12CACert.crt
+p p inhibitPolicyMapping1P12subCACert.crt
+p p inhibitPolicyMapping1P12subCAIPM5Cert.crt
+p p inhibitPolicyMapping1P12subsubCACert.crt
+p p inhibitPolicyMapping1P12subsubCAIPM5Cert.crt
+p p inhibitPolicyMapping1P1CACert.crt
+
+# For yet unknown reasons gpgsm claims a bad signature.
+? ? inhibitPolicyMapping1P1SelfIssuedCACert.crt
+? ? inhibitPolicyMapping1P1SelfIssuedsubCACert.crt
+? ? inhibitPolicyMapping1P1subCACert.crt
+
+p p inhibitPolicyMapping1P1subsubCACert.crt
+p p inhibitPolicyMapping5CACert.crt
+p p inhibitPolicyMapping5subCACert.crt
+p p inhibitPolicyMapping5subsubCACert.crt
+p p inhibitPolicyMapping5subsubsubCACert.crt
+p p keyUsageCriticalcRLSignFalseCACert.crt
+p p keyUsageCriticalkeyCertSignFalseCACert.crt
+p p keyUsageNotCriticalCACert.crt
+p p keyUsageNotCriticalcRLSignFalseCACert.crt
+p p keyUsageNotCriticalkeyCertSignFalseCACert.crt
+p p nameConstraintsDN1CACert.crt
+
+# For yet unknown reasons gpgsm claims a bad signature.
+? ? nameConstraintsDN1SelfIssuedCACert.crt
+
+p p nameConstraintsDN1subCA1Cert.crt
+p p nameConstraintsDN1subCA2Cert.crt
+p p nameConstraintsDN1subCA3Cert.crt
+p p nameConstraintsDN2CACert.crt
+p p nameConstraintsDN3CACert.crt
+p p nameConstraintsDN3subCA1Cert.crt
+p p nameConstraintsDN3subCA2Cert.crt
+p p nameConstraintsDN4CACert.crt
+p p nameConstraintsDN5CACert.crt
+p p nameConstraintsDNS1CACert.crt
+p p nameConstraintsDNS2CACert.crt
+p p nameConstraintsRFC822CA1Cert.crt
+p p nameConstraintsRFC822CA2Cert.crt
+p p nameConstraintsRFC822CA3Cert.crt
+p p nameConstraintsURI1CACert.crt
+p p nameConstraintsURI2CACert.crt
+p p onlyContainsAttributeCertsCACert.crt
+p p onlyContainsCACertsCACert.crt
+p p onlyContainsUserCertsCACert.crt
+p p onlySomeReasonsCA1Cert.crt
+p p onlySomeReasonsCA2Cert.crt
+p p onlySomeReasonsCA3Cert.crt
+p p onlySomeReasonsCA4Cert.crt
+p p pathLenConstraint0CACert.crt
+
+# For yet unknown reasons gpgsm claims a bad signature.
+? ? pathLenConstraint0SelfIssuedCACert.crt
+? ? pathLenConstraint0subCA2Cert.crt
+
+p p pathLenConstraint0subCACert.crt
+p p pathLenConstraint1CACert.crt
+
+# For yet unknown reasons gpgsm claims a bad signature.
+? ? pathLenConstraint1SelfIssuedCACert.crt
+? ? pathLenConstraint1SelfIssuedsubCACert.crt
+? ? pathLenConstraint1subCACert.crt
+
+p p pathLenConstraint6CACert.crt
+p p pathLenConstraint6subCA0Cert.crt
+p p pathLenConstraint6subCA1Cert.crt
+p p pathLenConstraint6subCA4Cert.crt
+p p pathLenConstraint6subsubCA00Cert.crt
+p p pathLenConstraint6subsubCA11Cert.crt
+p p pathLenConstraint6subsubCA41Cert.crt
+p p pathLenConstraint6subsubsubCA11XCert.crt
+p p pathLenConstraint6subsubsubCA41XCert.crt
+p p pre2000CRLnextUpdateCACert.crt
+p p requireExplicitPolicy0CACert.crt
+p p requireExplicitPolicy0subCACert.crt
+p p requireExplicitPolicy0subsubCACert.crt
+p p requireExplicitPolicy0subsubsubCACert.crt
+p p requireExplicitPolicy10CACert.crt
+p p requireExplicitPolicy10subCACert.crt
+p p requireExplicitPolicy10subsubCACert.crt
+p p requireExplicitPolicy10subsubsubCACert.crt
+p p requireExplicitPolicy2CACert.crt
+
+# For yet unknown reasons gpgsm claims a bad signature.
+? ? requireExplicitPolicy2SelfIssuedCACert.crt
+? ? requireExplicitPolicy2SelfIssuedsubCACert.crt
+? ? requireExplicitPolicy2subCACert.crt
+
+p p requireExplicitPolicy4CACert.crt
+p p requireExplicitPolicy4subCACert.crt
+p p requireExplicitPolicy4subsubCACert.crt
+p p requireExplicitPolicy4subsubsubCACert.crt
+p p requireExplicitPolicy5CACert.crt
+p p requireExplicitPolicy5subCACert.crt
+p p requireExplicitPolicy5subsubCACert.crt
+p p requireExplicitPolicy5subsubsubCACert.crt
+p p requireExplicitPolicy7CACert.crt
+p p requireExplicitPolicy7subCARE2Cert.crt
+p p requireExplicitPolicy7subsubCARE2RE4Cert.crt
+p p requireExplicitPolicy7subsubsubCARE2RE4Cert.crt
+
diff --git a/tests/pkits/inittests b/tests/pkits/inittests
new file mode 100755
index 000000000..6af16de03
--- /dev/null
+++ b/tests/pkits/inittests
@@ -0,0 +1,94 @@
+#!/bin/sh
+# Copyright (C) 2004 Free Software Foundation, Inc. -*- sh -*-
+#
+# 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.
+
+set -e
+
+
+clean_files='
+ReadMe.txt pkits.ldif
+gpgsm.conf gpg-agent.conf trustlist.txt policies.txt pubring.kbx
+msg msg.sig msg.unsig
+'
+
+[ -z "$srcdir" ] && srcdir=.
+[ -z "$GPGSM" ] && GPGSM=../../sm/gpgsm
+
+if [ -f $srcdir/README ] \
+ && grep tests/pkits/README README >/dev/null 2>&1; then
+ :
+else
+ # During make distclean the Makefile has already been removed,
+ # so we need this extra test.
+ if ! grep gnupg-test-pkits-directory testdir.stamp >/dev/null 2>&1; then
+ echo "inittests: please cd to the tests/pkits directory first" >&2
+ exit 1
+ fi
+fi
+
+if [ "$1" = "--clean" ]; then
+ if [ -d private-keys-v1.d ]; then
+ rm private-keys-v1.d/* 2>/dev/null || true
+ rmdir private-keys-v1.d
+ fi
+ rm ${clean_files} testdir.stamp 2>/dev/null || true
+ for i in certs certpairs crls pkcs12 smime; do
+ if [ -d $i ]; then
+ rm $i/* 2>/dev/null || true
+ rmdir $i
+ fi
+ done
+ exit 0
+fi
+
+if [ "$GNUPGHOME" != "`pwd`" ]; then
+ echo "inittests: please set GNUPGHOME to the tests/pkits directory" >&2
+ exit 1
+fi
+
+if [ -n "$GPG_AGENT_INFO" ]; then
+ echo "inittests: please unset GPG_AGENT_INFO" >&2
+ exit 1
+fi
+
+if ! bunzip2 -c PKITS_data.tar.bz2 | tar xf - ; then
+ echo "inittests: failed to untar the test data" >&2
+ exit 1
+fi
+
+
+# A stamp file used with --clean
+echo gnupg-test-pkits-directory > testdir.stamp
+
+
+# Create the configuration scripts
+cat > gpgsm.conf <<EOF
+no-secmem-warning
+no-greeting
+batch
+disable-crl-checks
+agent-program ../../agent/gpg-agent
+EOF
+
+# Fixme: we need to write a dummy pinentry program
+cat > gpg-agent.conf <<EOF
+no-grab
+EOF
+
+# Mark the root CA trusted
+cat > trustlist.txt <<EOF
+# /CN=Trust Anchor/O=Test Certificates/C=US
+66:8A:47:56:A2:DC:88:FF:DA:B8:95:E1:3C:63:37:55:5F:0A:F7:BF S
+EOF
+
+# Define the standard policies as NIST test-policy-1
+#cat >policies.txt <<EOF
+#2.16.840.1.101.3.2.1.48.1
+#EOF
diff --git a/tests/pkits/runtest b/tests/pkits/runtest
new file mode 100755
index 000000000..f054a3498
--- /dev/null
+++ b/tests/pkits/runtest
@@ -0,0 +1,4 @@
+#!/bin/sh
+[ -x "$1" ] && exec $1 $2
+exec sh $1 $2
+
diff --git a/tests/pkits/validate-all-certs b/tests/pkits/validate-all-certs
new file mode 100755
index 000000000..f482fdb51
--- /dev/null
+++ b/tests/pkits/validate-all-certs
@@ -0,0 +1,55 @@
+#!/bin/sh
+# validate-all-certs -*- sh -*-
+# 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+
+. ${srcdir:-.}/common.sh || exit 2
+
+while read dummy flag name; do
+ case $dummy in \#*) continue;; esac
+ [ -z "$dummy" ] && continue;
+
+ if ${GPGSM} -q --import --with-validation --disable-crl-checks \
+ certs/$name ; then
+ if [ "$flag" = 'p' ]; then
+ pass "validating certificate \`$name' succeeded"
+ elif [ "$flag" = 'f' ]; then
+ fail "validating certificate \`$name' succeeded"
+ elif [ "$flag" = '?' ]; then
+ unresolved "validating certificate \`$name' succeeded"
+ elif [ "$flag" = 'u' ]; then
+ unsupported "validating certificate \`$name' succeeded"
+ else
+ info "validating certificate \`$name' succeeded - (flag=$flag)"
+ fi
+ else
+ if [ "$flag" = 'p' ]; then
+ fail "validating certificate \`$name' failed"
+ elif [ "$flag" = 'f' ]; then
+ pass "validating certificate \`$name' failed"
+ elif [ "$flag" = '?' ]; then
+ unresolved "validating certificate \`$name' failed"
+ elif [ "$flag" = 'u' ]; then
+ unsupported "validating certificate \`$name' failed"
+ else
+ info "validating certificate \`$name' failed - (flag=$flag)"
+ fi
+ fi
+done < $srcdir/import-all-certs.data
+
+final_result

File Metadata

Mime Type
text/x-diff
Expires
Tue, Jan 20, 6:44 AM (1 d, 5 h)
Storage Engine
local-disk
Storage Format
Raw Data
Storage Handle
07/5f/2ff60117789bef9c38d7f4719ec0

Event Timeline